vitest-dev / vitest

Next generation testing framework powered by Vite.
https://vitest.dev
MIT License
12.73k stars 1.15k forks source link

Scoped Fixtures #6157

Open V-Mann-Nick opened 2 months ago

V-Mann-Nick commented 2 months ago

Clear and concise description of the problem

When setting up a test, fixtures can have a different scope. Suppose we have two fixtures: 1) db - connection to a database possibly with migrations and an initial seed (expensive setup) global to the test module at hand (beforeAll/afterAll) 2) user - a user created in the db which should be setup and torn down on every test (beforeEach/afterEach)

Scope is also reflected in vitest-fixture. I don't know the exact relation to this project, but I was very happy to see that it was incorporated into vitest directly. But it does seem that there's no feature parity with vitest-fixture as I can't find a way to scope fixtures to the worker.

This makes it really hard to use if you have an expensive setup like described above that you want to only setup and tear down once per test module.

Suggested solution

I think the original vitest-fixture had a good approach at least in terms of API:

import { test as base } from "vitest-fixture";

export const test = base.extend<{}, {resource: string}>({
  resource: [async ({}, use) => {
    const resource = ...; // setup resource
    await use(resource, async () => {
      ...; // teardown resource
    });
  }, { scope: "worker" }],
});

I also would be interested in contributing this feature.

Alternative

No response

Additional context

There exists a similar issue with an overlapping scope: https://github.com/vitest-dev/vitest/issues/4953

@jakebiesinger-storyhealth writes:

Playwright has a notion of automatic fixtures, where the fixture is executed even if it is not part of the fixture dependency list in a test. This enables test writers to implicitly set up fixtures that are common to all tests of a type.

He writes about "common to all tests". While the { auto: true } option did solve this problem, it does not solve the issue that these fixtures are setup and torn down for each test (beforeEach/afterEach) which can potentially be costly.

Validations

sheremet-va commented 2 months ago

I also would be interested in contributing this feature.

Feel free to try, but it would require a lot of refactoring because scope: 'worker' is not the same as running them in beforeAll/afterAll, since these hooks will run for every file (so it's more like a scope: 'file') even if several files are running in the same worker (with --single-worker or --no-isolate).

V-Mann-Nick commented 2 months ago

It does sound like scope: 'file' is what I actually want. I might have time to work on it next week. Thanks for the quick response.