Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,10 @@ export default ({ mode }: { mode: string }) => {
text: 'Test Environment',
link: '/guide/environment',
},
{
text: 'Test Run Lifecycle',
link: '/guide/lifecycle',
},
{
text: 'Snapshot',
link: '/guide/snapshot',
Expand Down Expand Up @@ -858,7 +862,7 @@ export default ({ mode }: { mode: string }) => {
},
{
text: 'Advanced',
collapsed: true,
collapsed: false,
items: [
{
text: 'Getting Started',
Expand Down Expand Up @@ -947,7 +951,7 @@ export default ({ mode }: { mode: string }) => {
},
{
text: 'Advanced',
collapsed: true,
collapsed: false,
items: [
{
text: 'Vitest',
Expand Down
54 changes: 32 additions & 22 deletions docs/config/globalsetup.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,45 @@ outline: deep

- **Type:** `string | string[]`

Path to global setup files, relative to project root.
Path to global setup files relative to project [root](/config/root).

A global setup file can either export named functions `setup` and `teardown` or a `default` function that returns a teardown function ([example](https://github.com/vitest-dev/vitest/blob/main/test/global-setup/vitest.config.ts)).
A global setup file can either export named functions `setup` and `teardown` or a `default` function that returns a teardown function:

::: info
Multiple globalSetup files are possible. setup and teardown are executed sequentially with teardown in reverse order.
::: code-group
```js [exports]
export function setup(project) {
console.log('setup')
}

export function teardown() {
console.log('teardown')
}
```
```js [default]
export default function setup(project) {
console.log('setup')

return function teardown() {
console.log('teardown')
}
}
```
:::

::: warning
Global setup runs only if there is at least one running test. This means that global setup might start running during watch mode after test file is changed (the test file will wait for global setup to finish before running).
Note that the `setup` method and a `default` function receive a [test project](/api/advanced/test-project) as the first argument. The global setup is called before the test workers are created and only if there is at least one test queued, and teardown is called after all test files have finished running. In [watch mode](/config/watch), the teardown is called before the process is exited instead. If you need to reconfigure your setup before the test rerun, you can use [`onTestsRerun`](#handling-test-reruns) hook instead.

Beware that the global setup is running in a different global scope, so your tests don't have access to variables defined here. However, you can pass down serializable data to tests via [`provide`](#provide) method:
Multiple global setup files are possible. `setup` and `teardown` are executed sequentially with teardown in reverse order.

::: danger
Beware that the global setup is running in a different global scope before test workers are even created, so your tests don't have access to global variables defined here. However, you can pass down serializable data to tests via [`provide`](/config/provide) method and read them in your tests via `inject` imported from `vitest`:

:::code-group
```ts [example.test.js]
```ts [example.test.ts]
import { inject } from 'vitest'

inject('wsPort') === 3000
```
```ts [globalSetup.ts <Version>3.0.0</Version>]
```ts [globalSetup.ts]
import type { TestProject } from 'vitest/node'

export default function setup(project: TestProject) {
Expand All @@ -39,22 +58,13 @@ declare module 'vitest' {
}
}
```
```ts [globalSetup.ts <Version>2.0.0</Version>]
import type { GlobalSetupContext } from 'vitest/node'

export default function setup({ provide }: GlobalSetupContext) {
provide('wsPort', 3000)
}

declare module 'vitest' {
export interface ProvidedContext {
wsPort: number
}
}
```
If you need to execute code in the same process as tests, use [`setupFiles`](/config/setupfiles) instead, but note that it runs before every test file.
:::

Since Vitest 3, you can define a custom callback function to be called when Vitest reruns tests. If the function is asynchronous, the runner will wait for it to complete before executing tests. Note that you cannot destruct the `project` like `{ onTestsRerun }` because it relies on the context.
### Handling Test Reruns

You can define a custom callback function to be called when Vitest reruns tests. The test runner will wait for it to complete before executing tests. Note that you cannot destruct the `project` like `{ onTestsRerun }` because it relies on the context.

```ts [globalSetup.ts]
import type { TestProject } from 'vitest/node'
Expand Down
4 changes: 2 additions & 2 deletions docs/config/sequence.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Sharding is happening before sorting, and only if `--shard` option is provided.

If [`sequencer.groupOrder`](#grouporder) is specified, the sequencer will be called once for each group and pool.

## groupOrder
## sequence.groupOrder

- **Type:** `number`
- **Default:** `0`
Expand Down Expand Up @@ -97,7 +97,7 @@ Tests in these projects will run in this order:

If you want files and tests to run randomly, you can enable it with this option, or CLI argument [`--sequence.shuffle`](/guide/cli).

Vitest usually uses cache to sort tests, so long running tests start earlier - this makes tests run faster. If your files and tests will run in random order you will lose this performance improvement, but it may be useful to track tests that accidentally depend on another run previously.
Vitest usually uses cache to sort tests, so long-running tests start earlier, which makes tests run faster. If your files and tests run in random order, you will lose this performance improvement, but it may be useful to track tests that accidentally depend on another test run previously.

### sequence.shuffle.files {#sequence-shuffle-files}

Expand Down
22 changes: 14 additions & 8 deletions docs/config/setupfiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,39 @@ outline: deep

- **Type:** `string | string[]`

Path to setup files. They will be run before each test file.
Paths to setup files resolved relative to the [`root`](/config/root). They will run before each _test file_ in the same process. By default, all test files run in parallel, but you can configure it with [`sequence.setupFiles`](/config/sequence#sequence-setupfiles) option.

Vitest will ignore any exports from these files.

:::warning
Note that setup files are executed in the same process as tests, unlike [`globalSetup`](/config/globalsetup) that runs once in the main thread before any test worker is created.
:::

:::info
Editing a setup file will automatically trigger a rerun of all tests.
:::

You can use `process.env.VITEST_POOL_ID` (integer-like string) inside to distinguish between workers.
If you have a heavy process running in the background, you can use `process.env.VITEST_POOL_ID` (integer-like string) inside to distinguish between workers and spread the workload.

:::tip
Note, that if you are running [`--isolate=false`](#isolate), this setup file will be run in the same global scope multiple times. Meaning, that you are accessing the same global object before each test, so make sure you are not doing the same thing more than you need.
:::
:::warning
If [isolation](/config/isolate) is disabled, imported modules are cached, but the setup file itself is executed again before each test file, meaning that you are accessing the same global object before each test file. Make sure you are not doing the same thing more than necessary.

For example, you may rely on a global variable:

```ts
import { config } from '@some-testing-lib'

if (!globalThis.defined) {
if (!globalThis.setupInitialized) {
config.plugins = [myCoolPlugin]
computeHeavyThing()
globalThis.defined = true
globalThis.setupInitialized = true
}

// hooks are reset before each suite
// hooks reset before each test file
afterEach(() => {
cleanup()
})

globalThis.resetBeforeEachTest = true
```
:::
Loading