···11+---
22+outline: deep
33+---
44+55+# describe
66+77+- **Alias:** `suite`
88+99+```ts
1010+function describe(
1111+ name: string | Function,
1212+ body?: () => unknown,
1313+ timeout?: number
1414+): void
1515+function describe(
1616+ name: string | Function,
1717+ options: SuiteOptions,
1818+ body?: () => unknown,
1919+): void
2020+```
2121+2222+`describe` is used to group related tests and benchmarks into a suite. Suites help organize your test files by creating logical blocks, making test output easier to read and enabling shared setup/teardown through [lifecycle hooks](/api/hooks).
2323+2424+When you use `test` in the top level of file, they are collected as part of the implicit suite for it. Using `describe` you can define a new suite in the current context, as a set of related tests or benchmarks and other nested suites.
2525+2626+```ts [basic.spec.ts]
2727+import { describe, expect, test } from 'vitest'
2828+2929+const person = {
3030+ isActive: true,
3131+ age: 32,
3232+}
3333+3434+describe('person', () => {
3535+ test('person is defined', () => {
3636+ expect(person).toBeDefined()
3737+ })
3838+3939+ test('is active', () => {
4040+ expect(person.isActive).toBeTruthy()
4141+ })
4242+4343+ test('age limit', () => {
4444+ expect(person.age).toBeLessThanOrEqual(32)
4545+ })
4646+})
4747+```
4848+4949+You can also nest `describe` blocks if you have a hierarchy of tests:
5050+5151+```ts
5252+import { describe, expect, test } from 'vitest'
5353+5454+function numberToCurrency(value: number | string) {
5555+ if (typeof value !== 'number') {
5656+ throw new TypeError('Value must be a number')
5757+ }
5858+5959+ return value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
6060+}
6161+6262+describe('numberToCurrency', () => {
6363+ describe('given an invalid number', () => {
6464+ test('composed of non-numbers to throw error', () => {
6565+ expect(() => numberToCurrency('abc')).toThrowError()
6666+ })
6767+ })
6868+6969+ describe('given a valid number', () => {
7070+ test('returns the correct currency format', () => {
7171+ expect(numberToCurrency(10000)).toBe('10,000.00')
7272+ })
7373+ })
7474+})
7575+```
7676+7777+## Test Options
7878+7979+You can use [test options](/api/test#test-options) to apply configuration to every test inside a suite, including nested suites. This is useful when you want to set timeouts, retries, or other options for a group of related tests.
8080+8181+```ts
8282+import { describe, test } from 'vitest'
8383+8484+describe('slow tests', { timeout: 10_000 }, () => {
8585+ test('test 1', () => { /* ... */ })
8686+ test('test 2', () => { /* ... */ })
8787+8888+ // nested suites also inherit the timeout
8989+ describe('nested', () => {
9090+ test('test 3', () => { /* ... */ })
9191+ })
9292+})
9393+```
9494+9595+### `shuffle`
9696+9797+- **Type:** `boolean`
9898+- **Default:** `false` (configured by [`sequence.shuffle`](/config/sequence#sequence-shuffle))
9999+- **Alias:** [`describe.shuffle`](#describe-shuffle)
100100+101101+Run tests within the suite in random order. This option is inherited by nested suites.
102102+103103+```ts
104104+import { describe, test } from 'vitest'
105105+106106+describe('randomized tests', { shuffle: true }, () => {
107107+ test('test 1', () => { /* ... */ })
108108+ test('test 2', () => { /* ... */ })
109109+ test('test 3', () => { /* ... */ })
110110+})
111111+```
112112+113113+## describe.skip
114114+115115+- **Alias:** `suite.skip`
116116+117117+Use `describe.skip` in a suite to avoid running a particular describe block.
118118+119119+```ts
120120+import { assert, describe, test } from 'vitest'
121121+122122+describe.skip('skipped suite', () => {
123123+ test('sqrt', () => {
124124+ // Suite skipped, no error
125125+ assert.equal(Math.sqrt(4), 3)
126126+ })
127127+})
128128+```
129129+130130+## describe.skipIf
131131+132132+- **Alias:** `suite.skipIf`
133133+134134+In some cases, you might run suites multiple times with different environments, and some of the suites might be environment-specific. Instead of wrapping the suite with `if`, you can use `describe.skipIf` to skip the suite whenever the condition is truthy.
135135+136136+```ts
137137+import { describe, test } from 'vitest'
138138+139139+const isDev = process.env.NODE_ENV === 'development'
140140+141141+describe.skipIf(isDev)('prod only test suite', () => {
142142+ // this test suite only runs in production
143143+})
144144+```
145145+146146+## describe.runIf
147147+148148+- **Alias:** `suite.runIf`
149149+150150+Opposite of [describe.skipIf](#describe-skipif).
151151+152152+```ts
153153+import { assert, describe, test } from 'vitest'
154154+155155+const isDev = process.env.NODE_ENV === 'development'
156156+157157+describe.runIf(isDev)('dev only test suite', () => {
158158+ // this test suite only runs in development
159159+})
160160+```
161161+162162+## describe.only
163163+164164+- **Alias:** `suite.only`
165165+166166+Use `describe.only` to only run certain suites
167167+168168+```ts
169169+import { assert, describe, test } from 'vitest'
170170+171171+// Only this suite (and others marked with only) are run
172172+describe.only('suite', () => {
173173+ test('sqrt', () => {
174174+ assert.equal(Math.sqrt(4), 3)
175175+ })
176176+})
177177+178178+describe('other suite', () => {
179179+ // ... will be skipped
180180+})
181181+```
182182+183183+Sometimes it is very useful to run `only` tests in a certain file, ignoring all other tests from the whole test suite, which pollute the output.
184184+185185+In order to do that, run `vitest` with specific file containing the tests in question:
186186+187187+```shell
188188+vitest interesting.test.ts
189189+```
190190+191191+## describe.concurrent
192192+193193+- **Alias:** `suite.concurrent`
194194+195195+`describe.concurrent` runs all inner suites and tests in parallel
196196+197197+```ts
198198+import { describe, test } from 'vitest'
199199+200200+// All suites and tests within this suite will be run in parallel
201201+describe.concurrent('suite', () => {
202202+ test('concurrent test 1', async () => { /* ... */ })
203203+ describe('concurrent suite 2', async () => {
204204+ test('concurrent test inner 1', async () => { /* ... */ })
205205+ test('concurrent test inner 2', async () => { /* ... */ })
206206+ })
207207+ test.concurrent('concurrent test 3', async () => { /* ... */ })
208208+})
209209+```
210210+211211+`.skip`, `.only`, and `.todo` works with concurrent suites. All the following combinations are valid:
212212+213213+```ts
214214+describe.concurrent(/* ... */)
215215+describe.skip.concurrent(/* ... */) // or describe.concurrent.skip(/* ... */)
216216+describe.only.concurrent(/* ... */) // or describe.concurrent.only(/* ... */)
217217+describe.todo.concurrent(/* ... */) // or describe.concurrent.todo(/* ... */)
218218+```
219219+220220+When running concurrent tests, Snapshots and Assertions must use `expect` from the local [Test Context](/guide/test-context) to ensure the right test is detected.
221221+222222+```ts
223223+describe.concurrent('suite', () => {
224224+ test('concurrent test 1', async ({ expect }) => {
225225+ expect(foo).toMatchSnapshot()
226226+ })
227227+ test('concurrent test 2', async ({ expect }) => {
228228+ expect(foo).toMatchSnapshot()
229229+ })
230230+})
231231+```
232232+233233+## describe.sequential
234234+235235+- **Alias:** `suite.sequential`
236236+237237+`describe.sequential` in a suite marks every test as sequential. This is useful if you want to run tests in sequence within `describe.concurrent` or with the `--sequence.concurrent` command option.
238238+239239+```ts
240240+import { describe, test } from 'vitest'
241241+242242+describe.concurrent('suite', () => {
243243+ test('concurrent test 1', async () => { /* ... */ })
244244+ test('concurrent test 2', async () => { /* ... */ })
245245+246246+ describe.sequential('', () => {
247247+ test('sequential test 1', async () => { /* ... */ })
248248+ test('sequential test 2', async () => { /* ... */ })
249249+ })
250250+})
251251+```
252252+253253+## describe.shuffle
254254+255255+- **Alias:** `suite.shuffle`
256256+257257+Vitest provides a way to run all tests in random order via CLI flag [`--sequence.shuffle`](/guide/cli) or config option [`sequence.shuffle`](/config/#sequence-shuffle), but if you want to have only part of your test suite to run tests in random order, you can mark it with this flag.
258258+259259+```ts
260260+import { describe, test } from 'vitest'
261261+262262+// or describe('suite', { shuffle: true }, ...)
263263+describe.shuffle('suite', () => {
264264+ test('random test 1', async () => { /* ... */ })
265265+ test('random test 2', async () => { /* ... */ })
266266+ test('random test 3', async () => { /* ... */ })
267267+268268+ // `shuffle` is inherited
269269+ describe('still random', () => {
270270+ test('random 4.1', async () => { /* ... */ })
271271+ test('random 4.2', async () => { /* ... */ })
272272+ })
273273+274274+ // disable shuffle inside
275275+ describe('not random', { shuffle: false }, () => {
276276+ test('in order 5.1', async () => { /* ... */ })
277277+ test('in order 5.2', async () => { /* ... */ })
278278+ })
279279+})
280280+// order depends on sequence.seed option in config (Date.now() by default)
281281+```
282282+283283+`.skip`, `.only`, and `.todo` works with random suites.
284284+285285+## describe.todo
286286+287287+- **Alias:** `suite.todo`
288288+289289+Use `describe.todo` to stub suites to be implemented later. An entry will be shown in the report for the tests so you know how many tests you still need to implement.
290290+291291+```ts
292292+// An entry will be shown in the report for this suite
293293+describe.todo('unimplemented suite')
294294+```
295295+296296+## describe.each
297297+298298+- **Alias:** `suite.each`
299299+300300+::: tip
301301+While `describe.each` is provided for Jest compatibility,
302302+Vitest also has [`describe.for`](#describe-for) which simplifies argument types and aligns with [`test.for`](/api/test#test-for).
303303+:::
304304+305305+Use `describe.each` if you have more than one test that depends on the same data.
306306+307307+```ts
308308+import { describe, expect, test } from 'vitest'
309309+310310+describe.each([
311311+ { a: 1, b: 1, expected: 2 },
312312+ { a: 1, b: 2, expected: 3 },
313313+ { a: 2, b: 1, expected: 3 },
314314+])('describe object add($a, $b)', ({ a, b, expected }) => {
315315+ test(`returns ${expected}`, () => {
316316+ expect(a + b).toBe(expected)
317317+ })
318318+319319+ test(`returned value not be greater than ${expected}`, () => {
320320+ expect(a + b).not.toBeGreaterThan(expected)
321321+ })
322322+323323+ test(`returned value not be less than ${expected}`, () => {
324324+ expect(a + b).not.toBeLessThan(expected)
325325+ })
326326+})
327327+```
328328+329329+* First row should be column names, separated by `|`;
330330+* One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
331331+332332+```ts
333333+import { describe, expect, test } from 'vitest'
334334+335335+describe.each`
336336+ a | b | expected
337337+ ${1} | ${1} | ${2}
338338+ ${'a'} | ${'b'} | ${'ab'}
339339+ ${[]} | ${'b'} | ${'b'}
340340+ ${{}} | ${'b'} | ${'[object Object]b'}
341341+ ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
342342+`('describe template string add($a, $b)', ({ a, b, expected }) => {
343343+ test(`returns ${expected}`, () => {
344344+ expect(a + b).toBe(expected)
345345+ })
346346+})
347347+```
348348+349349+## describe.for
350350+351351+- **Alias:** `suite.for`
352352+353353+The difference from `describe.each` is how array case is provided in the arguments.
354354+Other non array case (including template string usage) works exactly same.
355355+356356+```ts
357357+// `each` spreads array case
358358+describe.each([
359359+ [1, 1, 2],
360360+ [1, 2, 3],
361361+ [2, 1, 3],
362362+])('add(%i, %i) -> %i', (a, b, expected) => { // [!code --]
363363+ test('test', () => {
364364+ expect(a + b).toBe(expected)
365365+ })
366366+})
367367+368368+// `for` doesn't spread array case
369369+describe.for([
370370+ [1, 1, 2],
371371+ [1, 2, 3],
372372+ [2, 1, 3],
373373+])('add(%i, %i) -> %i', ([a, b, expected]) => { // [!code ++]
374374+ test('test', () => {
375375+ expect(a + b).toBe(expected)
376376+ })
377377+})
378378+```
+2-2
docs/api/expect.md
···3131expect(input).toBe(2) // jest API
3232```
33333434-Technically this example doesn't use [`test`](/api/#test) function, so in the console you will see Node.js error instead of Vitest output. To learn more about `test`, please read [Test API Reference](/api/).
3434+Technically this example doesn't use [`test`](/api/test) function, so in the console you will see Node.js error instead of Vitest output. To learn more about `test`, please read [Test API Reference](/api/test).
35353636Also, `expect` can be used statically to access matcher functions, described later, and more.
3737···9898```
9999100100::: warning
101101-`expect.soft` can only be used inside the [`test`](/api/#test) function.
101101+`expect.soft` can only be used inside the [`test`](/api/test) function.
102102:::
103103104104## poll
+461
docs/api/hooks.md
···11+---
22+outline: deep
33+---
44+55+# Hooks
66+77+These functions allow you to hook into the life cycle of tests to avoid repeating setup and teardown code. They apply to the current context: the file if they are used at the top-level or the current suite if they are inside a `describe` block. These hooks are not called, when you are running Vitest as a [type checker](/guide/testing-types).
88+99+Test hooks are called in a stack order ("after" hooks are reversed) by default, but you can configure it via [`sequence.hooks`](/config/sequence#sequence-hooks) option.
1010+1111+## beforeEach
1212+1313+```ts
1414+function beforeEach(
1515+ body: () => unknown,
1616+ timeout?: number,
1717+): void
1818+```
1919+2020+Register a callback to be called before each of the tests in the current suite runs.
2121+If the function returns a promise, Vitest waits until the promise resolve before running the test.
2222+2323+Optionally, you can pass a timeout (in milliseconds) defining how long to wait before terminating. The default is 10 seconds, and can be configured globally with [`hookTimeout`](/config/hooktimeout).
2424+2525+```ts
2626+import { beforeEach } from 'vitest'
2727+2828+beforeEach(async () => {
2929+ // Clear mocks and add some testing data before each test run
3030+ await stopMocking()
3131+ await addUser({ name: 'John' })
3232+})
3333+```
3434+3535+Here, the `beforeEach` ensures that user is added for each test.
3636+3737+`beforeEach` can also return an optional cleanup function (equivalent to [`afterEach`](#aftereach)):
3838+3939+```ts
4040+import { beforeEach } from 'vitest'
4141+4242+beforeEach(async () => {
4343+ // called once before each test run
4444+ await prepareSomething()
4545+4646+ // clean up function, called once after each test run
4747+ return async () => {
4848+ await resetSomething()
4949+ }
5050+})
5151+```
5252+5353+## afterEach
5454+5555+```ts
5656+function afterEach(
5757+ body: () => unknown,
5858+ timeout?: number,
5959+): void
6060+```
6161+6262+Register a callback to be called after each one of the tests in the current suite completes.
6363+If the function returns a promise, Vitest waits until the promise resolve before continuing.
6464+6565+Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 10 seconds, and can be configured globally with [`hookTimeout`](/config/hooktimeout).
6666+6767+```ts
6868+import { afterEach } from 'vitest'
6969+7070+afterEach(async () => {
7171+ await clearTestingData() // clear testing data after each test run
7272+})
7373+```
7474+7575+Here, the `afterEach` ensures that testing data is cleared after each test runs.
7676+7777+::: tip
7878+You can also use [`onTestFinished`](#ontestfinished) during the test execution to cleanup any state after the test has finished running.
7979+:::
8080+8181+## beforeAll
8282+8383+```ts
8484+function beforeAll(
8585+ body: () => unknown,
8686+ timeout?: number,
8787+): void
8888+```
8989+9090+Register a callback to be called once before starting to run all tests in the current suite.
9191+If the function returns a promise, Vitest waits until the promise resolve before running tests.
9292+9393+Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 10 seconds, and can be configured globally with [`hookTimeout`](/config/hooktimeout).
9494+9595+```ts
9696+import { beforeAll } from 'vitest'
9797+9898+beforeAll(async () => {
9999+ await startMocking() // called once before all tests run
100100+})
101101+```
102102+103103+Here the `beforeAll` ensures that the mock data is set up before tests run.
104104+105105+`beforeAll` can also return an optional cleanup function (equivalent to [`afterAll`](#afterall)):
106106+107107+```ts
108108+import { beforeAll } from 'vitest'
109109+110110+beforeAll(async () => {
111111+ // called once before all tests run
112112+ await startMocking()
113113+114114+ // clean up function, called once after all tests run
115115+ return async () => {
116116+ await stopMocking()
117117+ }
118118+})
119119+```
120120+121121+## afterAll
122122+123123+```ts
124124+function afterAll(
125125+ body: () => unknown,
126126+ timeout?: number,
127127+): void
128128+```
129129+130130+Register a callback to be called once after all tests have run in the current suite.
131131+If the function returns a promise, Vitest waits until the promise resolve before continuing.
132132+133133+Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 10 seconds, and can be configured globally with [`hookTimeout`](/config/hooktimeout).
134134+135135+```ts
136136+import { afterAll } from 'vitest'
137137+138138+afterAll(async () => {
139139+ await stopMocking() // this method is called after all tests run
140140+})
141141+```
142142+143143+Here the `afterAll` ensures that `stopMocking` method is called after all tests run.
144144+145145+## aroundEach
146146+147147+```ts
148148+function aroundEach(
149149+ body: (runTest: () => Promise<void>, context: TestContext) => Promise<void>,
150150+ timeout?: number,
151151+): void
152152+```
153153+154154+Register a callback function that wraps around each test within the current suite. The callback receives a `runTest` function that **must** be called to run the test.
155155+156156+The `runTest()` function runs `beforeEach` hooks, the test itself, fixtures accessed in the test, and `afterEach` hooks. Fixtures that are accessed in the `aroundEach` callback are initialized before `runTest()` is called and are torn down after the aroundEach teardown code completes, allowing you to safely use them in both setup and teardown phases.
157157+158158+::: warning
159159+You **must** call `runTest()` within your callback. If `runTest()` is not called, the test will fail with an error.
160160+:::
161161+162162+Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The timeout applies independently to the setup phase (before `runTest()`) and teardown phase (after `runTest()`). The default is 10 seconds, and can be configured globally with [`hookTimeout`](/config/hooktimeout).
163163+164164+```ts
165165+import { aroundEach, test } from 'vitest'
166166+167167+aroundEach(async (runTest) => {
168168+ await db.transaction(runTest)
169169+})
170170+171171+test('insert user', async () => {
172172+ await db.insert({ name: 'Alice' })
173173+ // transaction is automatically rolled back after the test
174174+})
175175+```
176176+177177+::: tip When to use `aroundEach`
178178+Use `aroundEach` when your test needs to run **inside a context** that wraps around it, such as:
179179+- Wrapping tests in [AsyncLocalStorage](https://nodejs.org/api/async_context.html#class-asynclocalstorage) context
180180+- Wrapping tests with tracing spans
181181+- Database transactions
182182+183183+If you just need to run code before and after tests, prefer using [`beforeEach`](#beforeeach) with a cleanup return function:
184184+```ts
185185+beforeEach(async () => {
186186+ await database.connect()
187187+ return async () => {
188188+ await database.disconnect()
189189+ }
190190+})
191191+```
192192+:::
193193+194194+### Multiple Hooks
195195+196196+When multiple `aroundEach` hooks are registered, they are nested inside each other. The first registered hook is the outermost wrapper:
197197+198198+```ts
199199+aroundEach(async (runTest) => {
200200+ console.log('outer before')
201201+ await runTest()
202202+ console.log('outer after')
203203+})
204204+205205+aroundEach(async (runTest) => {
206206+ console.log('inner before')
207207+ await runTest()
208208+ console.log('inner after')
209209+})
210210+211211+// Output order:
212212+// outer before
213213+// inner before
214214+// test
215215+// inner after
216216+// outer after
217217+```
218218+219219+### Context and Fixtures
220220+221221+The callback receives the test context as the second argument which means that you can use fixtures with `aroundEach`:
222222+223223+```ts
224224+import { aroundEach, test as base } from 'vitest'
225225+226226+const test = base.extend<{ db: Database; user: User }>({
227227+ db: async ({}, use) => {
228228+ // db is created before `aroundEach` hook
229229+ const db = await createTestDatabase()
230230+ await use(db)
231231+ await db.close()
232232+ },
233233+ user: async ({ db }, use) => {
234234+ // `user` runs as part of the transaction
235235+ // because it's accessed inside the `test`
236236+ const user = await db.createUser()
237237+ await use(user)
238238+ },
239239+})
240240+241241+// note that `aroundEach` is available on test
242242+// for a better TypeScript support of fixtures
243243+test.aroundEach(async (runTest, { db }) => {
244244+ await db.transaction(runTest)
245245+})
246246+247247+test('insert user', async ({ db, user }) => {
248248+ await db.insert(user)
249249+})
250250+```
251251+252252+## aroundAll
253253+254254+```ts
255255+function aroundAll(
256256+ body: (runSuite: () => Promise<void>) => Promise<void>,
257257+ timeout?: number,
258258+): void
259259+```
260260+261261+Register a callback function that wraps around all tests within the current suite. The callback receives a `runSuite` function that **must** be called to run the suite's tests.
262262+263263+The `runSuite()` function runs all tests in the suite, including `beforeAll`/`afterAll`/`beforeEach`/`afterEach` hooks, `aroundEach` hooks, and fixtures.
264264+265265+::: warning
266266+You **must** call `runSuite()` within your callback. If `runSuite()` is not called, the hook will fail with an error and all tests in the suite will be skipped.
267267+:::
268268+269269+Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The timeout applies independently to the setup phase (before `runSuite()`) and teardown phase (after `runSuite()`). The default is 10 seconds, and can be configured globally with [`hookTimeout`](/config/hooktimeout).
270270+271271+```ts
272272+import { aroundAll, test } from 'vitest'
273273+274274+aroundAll(async (runSuite) => {
275275+ await tracer.trace('test-suite', runSuite)
276276+})
277277+278278+test('test 1', () => {
279279+ // Runs within the tracing span
280280+})
281281+282282+test('test 2', () => {
283283+ // Also runs within the same tracing span
284284+})
285285+```
286286+287287+::: tip When to use `aroundAll`
288288+Use `aroundAll` when your suite needs to run **inside a context** that wraps around all tests, such as:
289289+- Wrapping an entire suite in [AsyncLocalStorage](https://nodejs.org/api/async_context.html#class-asynclocalstorage) context
290290+- Wrapping a suite with tracing spans
291291+- Database transactions
292292+293293+If you just need to run code once before and after all tests, prefer using [`beforeAll`](#beforeall) with a cleanup return function:
294294+```ts
295295+beforeAll(async () => {
296296+ await server.start()
297297+ return async () => {
298298+ await server.stop()
299299+ }
300300+})
301301+```
302302+:::
303303+304304+### Multiple Hooks
305305+306306+When multiple `aroundAll` hooks are registered, they are nested inside each other. The first registered hook is the outermost wrapper:
307307+308308+```ts
309309+aroundAll(async (runSuite) => {
310310+ console.log('outer before')
311311+ await runSuite()
312312+ console.log('outer after')
313313+})
314314+315315+aroundAll(async (runSuite) => {
316316+ console.log('inner before')
317317+ await runSuite()
318318+ console.log('inner after')
319319+})
320320+321321+// Output order: outer before → inner before → tests → inner after → outer after
322322+```
323323+324324+Each suite has its own independent `aroundAll` hooks. Parent suite's `aroundAll` wraps around child suite's execution:
325325+326326+```ts
327327+import { AsyncLocalStorage } from 'node:async_hooks'
328328+import { aroundAll, describe, test } from 'vitest'
329329+330330+const context = new AsyncLocalStorage<{ suiteId: string }>()
331331+332332+aroundAll(async (runSuite) => {
333333+ await context.run({ suiteId: 'root' }, runSuite)
334334+})
335335+336336+test('root test', () => {
337337+ // context.getStore() returns { suiteId: 'root' }
338338+})
339339+340340+describe('nested', () => {
341341+ aroundAll(async (runSuite) => {
342342+ // Parent's context is available here
343343+ await context.run({ suiteId: 'nested' }, runSuite)
344344+ })
345345+346346+ test('nested test', () => {
347347+ // context.getStore() returns { suiteId: 'nested' }
348348+ })
349349+})
350350+```
351351+352352+## Test Hooks
353353+354354+Vitest provides a few hooks that you can call _during_ the test execution to cleanup the state when the test has finished running.
355355+356356+::: warning
357357+These hooks will throw an error if they are called outside of the test body.
358358+:::
359359+360360+### onTestFinished {#ontestfinished}
361361+362362+This hook is always called after the test has finished running. It is called after `afterEach` hooks since they can influence the test result. It receives an `TestContext` object like `beforeEach` and `afterEach`.
363363+364364+```ts {1,5}
365365+import { onTestFinished, test } from 'vitest'
366366+367367+test('performs a query', () => {
368368+ const db = connectDb()
369369+ onTestFinished(() => db.close())
370370+ db.query('SELECT * FROM users')
371371+})
372372+```
373373+374374+::: warning
375375+If you are running tests concurrently, you should always use `onTestFinished` hook from the test context since Vitest doesn't track concurrent tests in global hooks:
376376+377377+```ts {3,5}
378378+import { test } from 'vitest'
379379+380380+test.concurrent('performs a query', ({ onTestFinished }) => {
381381+ const db = connectDb()
382382+ onTestFinished(() => db.close())
383383+ db.query('SELECT * FROM users')
384384+})
385385+```
386386+:::
387387+388388+This hook is particularly useful when creating reusable logic:
389389+390390+```ts
391391+// this can be in a separate file
392392+function getTestDb() {
393393+ const db = connectMockedDb()
394394+ onTestFinished(() => db.close())
395395+ return db
396396+}
397397+398398+test('performs a user query', async () => {
399399+ const db = getTestDb()
400400+ expect(
401401+ await db.query('SELECT * from users').perform()
402402+ ).toEqual([])
403403+})
404404+405405+test('performs an organization query', async () => {
406406+ const db = getTestDb()
407407+ expect(
408408+ await db.query('SELECT * from organizations').perform()
409409+ ).toEqual([])
410410+})
411411+```
412412+413413+It is also a good practice to cleanup your spies after each test, so they don't leak into other tests. You can do so by enabling [`restoreMocks`](/config/restoremocks) config globally, or restoring the spy inside `onTestFinished` (if you try to restore the mock at the end of the test, it won't be restored if one of the assertions fails - using `onTestFinished` ensures the code always runs):
414414+415415+```ts
416416+import { onTestFinished, test } from 'vitest'
417417+418418+test('performs a query', () => {
419419+ const spy = vi.spyOn(db, 'query')
420420+ onTestFinished(() => spy.mockClear())
421421+422422+ db.query('SELECT * FROM users')
423423+ expect(spy).toHaveBeenCalled()
424424+})
425425+```
426426+427427+::: tip
428428+This hook is always called in reverse order and is not affected by [`sequence.hooks`](/config/#sequence-hooks) option.
429429+:::
430430+431431+### onTestFailed
432432+433433+This hook is called only after the test has failed. It is called after `afterEach` hooks since they can influence the test result. It receives a `TestContext` object like `beforeEach` and `afterEach`. This hook is useful for debugging.
434434+435435+```ts {1,5-7}
436436+import { onTestFailed, test } from 'vitest'
437437+438438+test('performs a query', () => {
439439+ const db = connectDb()
440440+ onTestFailed(({ task }) => {
441441+ console.log(task.result.errors)
442442+ })
443443+ db.query('SELECT * FROM users')
444444+})
445445+```
446446+447447+::: warning
448448+If you are running tests concurrently, you should always use `onTestFailed` hook from the test context since Vitest doesn't track concurrent tests in global hooks:
449449+450450+```ts {3,5-7}
451451+import { test } from 'vitest'
452452+453453+test.concurrent('performs a query', ({ onTestFailed }) => {
454454+ const db = connectDb()
455455+ onTestFailed(({ task }) => {
456456+ console.log(task.result.errors)
457457+ })
458458+ db.query('SELECT * FROM users')
459459+})
460460+```
461461+:::
-1316
docs/api/index.md
···11----
22-outline: deep
33----
44-55-# Test API Reference
66-77-The following types are used in the type signatures below
88-99-```ts
1010-type Awaitable<T> = T | PromiseLike<T>
1111-type TestFunction = () => Awaitable<void>
1212-1313-interface TestOptions {
1414- /**
1515- * Will fail the test if it takes too long to execute
1616- */
1717- timeout?: number
1818- /**
1919- * Will retry the test specific number of times if it fails
2020- *
2121- * @default 0
2222- */
2323- retry?: number
2424- /**
2525- * Will repeat the same test several times even if it fails each time
2626- * If you have "retry" option and it fails, it will use every retry in each cycle
2727- * Useful for debugging random failings
2828- *
2929- * @default 0
3030- */
3131- repeats?: number
3232- /**
3333- * Custom tags of the test. Useful for filtering tests.
3434- */
3535- tags?: string[] | string
3636-}
3737-```
3838-3939-<!-- TODO: rewrite this into separate test files with options highlighted -->
4040-4141-When a test function returns a promise, the runner will wait until it is resolved to collect async expectations. If the promise is rejected, the test will fail.
4242-4343-::: tip
4444-In Jest, `TestFunction` can also be of type `(done: DoneCallback) => void`. If this form is used, the test will not be concluded until `done` is called. You can achieve the same using an `async` function, see the [Migration guide Done Callback section](/guide/migration#done-callback).
4545-:::
4646-4747-You can define options by chaining properties on a function:
4848-4949-```ts
5050-import { test } from 'vitest'
5151-5252-test.skip('skipped test', () => {
5353- // some logic that fails right now
5454-})
5555-5656-test.concurrent.skip('skipped concurrent test', () => {
5757- // some logic that fails right now
5858-})
5959-```
6060-6161-But you can also provide an object as a second argument instead:
6262-6363-```ts
6464-import { test } from 'vitest'
6565-6666-test('skipped test', { skip: true }, () => {
6767- // some logic that fails right now
6868-})
6969-7070-test('skipped concurrent test', { skip: true, concurrent: true }, () => {
7171- // some logic that fails right now
7272-})
7373-```
7474-7575-They both work in exactly the same way. To use either one is purely a stylistic choice.
7676-7777-Note that if you are providing timeout as the last argument, you cannot use options anymore:
7878-7979-```ts
8080-import { test } from 'vitest'
8181-8282-// ✅ this works
8383-test.skip('heavy test', () => {
8484- // ...
8585-}, 10_000)
8686-8787-// ❌ this doesn't work
8888-test('heavy test', { skip: true }, () => {
8989- // ...
9090-}, 10_000)
9191-```
9292-9393-However, you can provide a timeout inside the object:
9494-9595-```ts
9696-import { test } from 'vitest'
9797-9898-// ✅ this works
9999-test('heavy test', { skip: true, timeout: 10_000 }, () => {
100100- // ...
101101-})
102102-```
103103-104104-## test
105105-106106-- **Alias:** `it`
107107-108108-`test` defines a set of related expectations. It receives the test name and a function that holds the expectations to test.
109109-110110-Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds, and can be configured globally with [testTimeout](/config/#testtimeout)
111111-112112-```ts
113113-import { expect, test } from 'vitest'
114114-115115-test('should work as expected', () => {
116116- expect(Math.sqrt(4)).toBe(2)
117117-})
118118-```
119119-120120-### test.extend {#test-extended}
121121-122122-- **Alias:** `it.extend`
123123-124124-Use `test.extend` to extend the test context with custom fixtures. This will return a new `test` and it's also extendable, so you can compose more fixtures or override existing ones by extending it as you need. See [Extend Test Context](/guide/test-context.html#test-extend) for more information.
125125-126126-```ts
127127-import { expect, test } from 'vitest'
128128-129129-const todos = []
130130-const archive = []
131131-132132-const myTest = test.extend({
133133- todos: async ({ task }, use) => {
134134- todos.push(1, 2, 3)
135135- await use(todos)
136136- todos.length = 0
137137- },
138138- archive
139139-})
140140-141141-myTest('add item', ({ todos }) => {
142142- expect(todos.length).toBe(3)
143143-144144- todos.push(4)
145145- expect(todos.length).toBe(4)
146146-})
147147-```
148148-149149-### test.skip
150150-151151-- **Alias:** `it.skip`
152152-153153-If you want to skip running certain tests, but you don't want to delete the code due to any reason, you can use `test.skip` to avoid running them.
154154-155155-```ts
156156-import { assert, test } from 'vitest'
157157-158158-test.skip('skipped test', () => {
159159- // Test skipped, no error
160160- assert.equal(Math.sqrt(4), 3)
161161-})
162162-```
163163-164164-You can also skip test by calling `skip` on its [context](/guide/test-context) dynamically:
165165-166166-```ts
167167-import { assert, test } from 'vitest'
168168-169169-test('skipped test', (context) => {
170170- context.skip()
171171- // Test skipped, no error
172172- assert.equal(Math.sqrt(4), 3)
173173-})
174174-```
175175-176176-Since Vitest 3.1, if the condition is unknown, you can provide it to the `skip` method as the first arguments:
177177-178178-```ts
179179-import { assert, test } from 'vitest'
180180-181181-test('skipped test', (context) => {
182182- context.skip(Math.random() < 0.5, 'optional message')
183183- // Test skipped, no error
184184- assert.equal(Math.sqrt(4), 3)
185185-})
186186-```
187187-188188-### test.skipIf
189189-190190-- **Alias:** `it.skipIf`
191191-192192-In some cases you might run tests multiple times with different environments, and some of the tests might be environment-specific. Instead of wrapping the test code with `if`, you can use `test.skipIf` to skip the test whenever the condition is truthy.
193193-194194-```ts
195195-import { assert, test } from 'vitest'
196196-197197-const isDev = process.env.NODE_ENV === 'development'
198198-199199-test.skipIf(isDev)('prod only test', () => {
200200- // this test only runs in production
201201-})
202202-```
203203-204204-::: warning
205205-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
206206-:::
207207-208208-### test.runIf
209209-210210-- **Alias:** `it.runIf`
211211-212212-Opposite of [test.skipIf](#test-skipif).
213213-214214-```ts
215215-import { assert, test } from 'vitest'
216216-217217-const isDev = process.env.NODE_ENV === 'development'
218218-219219-test.runIf(isDev)('dev only test', () => {
220220- // this test only runs in development
221221-})
222222-```
223223-224224-::: warning
225225-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
226226-:::
227227-228228-### test.only
229229-230230-- **Alias:** `it.only`
231231-232232-Use `test.only` to only run certain tests in a given suite. This is useful when debugging.
233233-234234-Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds, and can be configured globally with [testTimeout](/config/#testtimeout).
235235-236236-```ts
237237-import { assert, test } from 'vitest'
238238-239239-test.only('test', () => {
240240- // Only this test (and others marked with only) are run
241241- assert.equal(Math.sqrt(4), 2)
242242-})
243243-```
244244-245245-Sometimes it is very useful to run `only` tests in a certain file, ignoring all other tests from the whole test suite, which pollute the output.
246246-247247-In order to do that run `vitest` with specific file containing the tests in question.
248248-```
249249-# vitest interesting.test.ts
250250-```
251251-252252-### test.concurrent
253253-254254-- **Alias:** `it.concurrent`
255255-256256-`test.concurrent` marks consecutive tests to be run in parallel. It receives the test name, an async function with the tests to collect, and an optional timeout (in milliseconds).
257257-258258-```ts
259259-import { describe, test } from 'vitest'
260260-261261-// The two tests marked with concurrent will be run in parallel
262262-describe('suite', () => {
263263- test('serial test', async () => { /* ... */ })
264264- test.concurrent('concurrent test 1', async () => { /* ... */ })
265265- test.concurrent('concurrent test 2', async () => { /* ... */ })
266266-})
267267-```
268268-269269-`test.skip`, `test.only`, and `test.todo` works with concurrent tests. All the following combinations are valid:
270270-271271-```ts
272272-test.concurrent(/* ... */)
273273-test.skip.concurrent(/* ... */) // or test.concurrent.skip(/* ... */)
274274-test.only.concurrent(/* ... */) // or test.concurrent.only(/* ... */)
275275-test.todo.concurrent(/* ... */) // or test.concurrent.todo(/* ... */)
276276-```
277277-278278-When running concurrent tests, Snapshots and Assertions must use `expect` from the local [Test Context](/guide/test-context.md) to ensure the right test is detected.
279279-280280-```ts
281281-test.concurrent('test 1', async ({ expect }) => {
282282- expect(foo).toMatchSnapshot()
283283-})
284284-test.concurrent('test 2', async ({ expect }) => {
285285- expect(foo).toMatchSnapshot()
286286-})
287287-```
288288-289289-::: warning
290290-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
291291-:::
292292-293293-### test.sequential
294294-295295-- **Alias:** `it.sequential`
296296-297297-`test.sequential` marks a test as sequential. This is useful if you want to run tests in sequence within `describe.concurrent` or with the `--sequence.concurrent` command option.
298298-299299-```ts
300300-import { describe, test } from 'vitest'
301301-302302-// with config option { sequence: { concurrent: true } }
303303-test('concurrent test 1', async () => { /* ... */ })
304304-test('concurrent test 2', async () => { /* ... */ })
305305-306306-test.sequential('sequential test 1', async () => { /* ... */ })
307307-test.sequential('sequential test 2', async () => { /* ... */ })
308308-309309-// within concurrent suite
310310-describe.concurrent('suite', () => {
311311- test('concurrent test 1', async () => { /* ... */ })
312312- test('concurrent test 2', async () => { /* ... */ })
313313-314314- test.sequential('sequential test 1', async () => { /* ... */ })
315315- test.sequential('sequential test 2', async () => { /* ... */ })
316316-})
317317-```
318318-319319-### test.todo
320320-321321-- **Alias:** `it.todo`
322322-323323-Use `test.todo` to stub tests to be implemented later. An entry will be shown in the report for the tests so you know how many tests you still need to implement.
324324-325325-```ts
326326-// An entry will be shown in the report for this test
327327-test.todo('unimplemented test')
328328-```
329329-330330-### test.fails
331331-332332-- **Alias:** `it.fails`
333333-334334-Use `test.fails` to indicate that an assertion will fail explicitly.
335335-336336-```ts
337337-import { expect, test } from 'vitest'
338338-339339-function myAsyncFunc() {
340340- return new Promise(resolve => resolve(1))
341341-}
342342-test.fails('fail test', async () => {
343343- await expect(myAsyncFunc()).rejects.toBe(1)
344344-})
345345-```
346346-347347-::: warning
348348-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
349349-:::
350350-351351-### test.each
352352-353353-- **Alias:** `it.each`
354354-355355-::: tip
356356-While `test.each` is provided for Jest compatibility,
357357-Vitest also has [`test.for`](#test-for) with an additional feature to integrate [`TestContext`](/guide/test-context).
358358-:::
359359-360360-Use `test.each` when you need to run the same test with different variables.
361361-You can inject parameters with [printf formatting](https://nodejs.org/api/util.html#util_util_format_format_args) in the test name in the order of the test function parameters.
362362-363363-- `%s`: string
364364-- `%d`: number
365365-- `%i`: integer
366366-- `%f`: floating point value
367367-- `%j`: json
368368-- `%o`: object
369369-- `%#`: 0-based index of the test case
370370-- `%$`: 1-based index of the test case
371371-- `%%`: single percent sign ('%')
372372-373373-```ts
374374-import { expect, test } from 'vitest'
375375-376376-test.each([
377377- [1, 1, 2],
378378- [1, 2, 3],
379379- [2, 1, 3],
380380-])('add(%i, %i) -> %i', (a, b, expected) => {
381381- expect(a + b).toBe(expected)
382382-})
383383-384384-// this will return
385385-// ✓ add(1, 1) -> 2
386386-// ✓ add(1, 2) -> 3
387387-// ✓ add(2, 1) -> 3
388388-```
389389-390390-You can also access object properties and array elements with `$` prefix:
391391-392392-```ts
393393-test.each([
394394- { a: 1, b: 1, expected: 2 },
395395- { a: 1, b: 2, expected: 3 },
396396- { a: 2, b: 1, expected: 3 },
397397-])('add($a, $b) -> $expected', ({ a, b, expected }) => {
398398- expect(a + b).toBe(expected)
399399-})
400400-401401-// this will return
402402-// ✓ add(1, 1) -> 2
403403-// ✓ add(1, 2) -> 3
404404-// ✓ add(2, 1) -> 3
405405-406406-test.each([
407407- [1, 1, 2],
408408- [1, 2, 3],
409409- [2, 1, 3],
410410-])('add($0, $1) -> $2', (a, b, expected) => {
411411- expect(a + b).toBe(expected)
412412-})
413413-414414-// this will return
415415-// ✓ add(1, 1) -> 2
416416-// ✓ add(1, 2) -> 3
417417-// ✓ add(2, 1) -> 3
418418-```
419419-420420-You can also access Object attributes with `.`, if you are using objects as arguments:
421421-422422- ```ts
423423- test.each`
424424- a | b | expected
425425- ${{ val: 1 }} | ${'b'} | ${'1b'}
426426- ${{ val: 2 }} | ${'b'} | ${'2b'}
427427- ${{ val: 3 }} | ${'b'} | ${'3b'}
428428- `('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
429429- expect(a.val + b).toBe(expected)
430430- })
431431-432432- // this will return
433433- // ✓ add(1, b) -> 1b
434434- // ✓ add(2, b) -> 2b
435435- // ✓ add(3, b) -> 3b
436436- ```
437437-438438-* First row should be column names, separated by `|`;
439439-* One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
440440-441441-```ts
442442-import { expect, test } from 'vitest'
443443-444444-test.each`
445445- a | b | expected
446446- ${1} | ${1} | ${2}
447447- ${'a'} | ${'b'} | ${'ab'}
448448- ${[]} | ${'b'} | ${'b'}
449449- ${{}} | ${'b'} | ${'[object Object]b'}
450450- ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
451451-`('returns $expected when $a is added $b', ({ a, b, expected }) => {
452452- expect(a + b).toBe(expected)
453453-})
454454-```
455455-456456-::: tip
457457-Vitest processes `$values` with Chai `format` method. If the value is too truncated, you can increase [chaiConfig.truncateThreshold](/config/#chaiconfig-truncatethreshold) in your config file.
458458-:::
459459-460460-::: warning
461461-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
462462-:::
463463-464464-### test.for
465465-466466-- **Alias:** `it.for`
467467-468468-Alternative to `test.each` to provide [`TestContext`](/guide/test-context).
469469-470470-The difference from `test.each` lies in how arrays are provided in the arguments.
471471-Non-array arguments to `test.for` (including template string usage) work exactly the same as for `test.each`.
472472-473473-```ts
474474-// `each` spreads arrays
475475-test.each([
476476- [1, 1, 2],
477477- [1, 2, 3],
478478- [2, 1, 3],
479479-])('add(%i, %i) -> %i', (a, b, expected) => { // [!code --]
480480- expect(a + b).toBe(expected)
481481-})
482482-483483-// `for` doesn't spread arrays (notice the square brackets around the arguments)
484484-test.for([
485485- [1, 1, 2],
486486- [1, 2, 3],
487487- [2, 1, 3],
488488-])('add(%i, %i) -> %i', ([a, b, expected]) => { // [!code ++]
489489- expect(a + b).toBe(expected)
490490-})
491491-```
492492-493493-The 2nd argument is [`TestContext`](/guide/test-context) and can be used for concurrent snapshots, for example:
494494-495495-```ts
496496-test.concurrent.for([
497497- [1, 1],
498498- [1, 2],
499499- [2, 1],
500500-])('add(%i, %i)', ([a, b], { expect }) => {
501501- expect(a + b).matchSnapshot()
502502-})
503503-```
504504-505505-## bench
506506-507507-- **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`
508508-509509-`bench` defines a benchmark. In Vitest terms, benchmark is a function that defines a series of operations. Vitest runs this function multiple times to display different performance results.
510510-511511-Vitest uses the [`tinybench`](https://github.com/tinylibs/tinybench) library under the hood, inheriting all its options that can be used as a third argument.
512512-513513-```ts
514514-import { bench } from 'vitest'
515515-516516-bench('normal sorting', () => {
517517- const x = [1, 5, 4, 2, 3]
518518- x.sort((a, b) => {
519519- return a - b
520520- })
521521-}, { time: 1000 })
522522-```
523523-524524-```ts
525525-export interface Options {
526526- /**
527527- * time needed for running a benchmark task (milliseconds)
528528- * @default 500
529529- */
530530- time?: number
531531-532532- /**
533533- * number of times that a task should run if even the time option is finished
534534- * @default 10
535535- */
536536- iterations?: number
537537-538538- /**
539539- * function to get the current timestamp in milliseconds
540540- */
541541- now?: () => number
542542-543543- /**
544544- * An AbortSignal for aborting the benchmark
545545- */
546546- signal?: AbortSignal
547547-548548- /**
549549- * Throw if a task fails (events will not work if true)
550550- */
551551- throws?: boolean
552552-553553- /**
554554- * warmup time (milliseconds)
555555- * @default 100ms
556556- */
557557- warmupTime?: number
558558-559559- /**
560560- * warmup iterations
561561- * @default 5
562562- */
563563- warmupIterations?: number
564564-565565- /**
566566- * setup function to run before each benchmark task (cycle)
567567- */
568568- setup?: Hook
569569-570570- /**
571571- * teardown function to run after each benchmark task (cycle)
572572- */
573573- teardown?: Hook
574574-}
575575-```
576576-After the test case is run, the output structure information is as follows:
577577-578578-```
579579- name hz min max mean p75 p99 p995 p999 rme samples
580580-· normal sorting 6,526,368.12 0.0001 0.3638 0.0002 0.0002 0.0002 0.0002 0.0004 ±1.41% 652638
581581-```
582582-```ts
583583-export interface TaskResult {
584584- /*
585585- * the last error that was thrown while running the task
586586- */
587587- error?: unknown
588588-589589- /**
590590- * The amount of time in milliseconds to run the benchmark task (cycle).
591591- */
592592- totalTime: number
593593-594594- /**
595595- * the minimum value in the samples
596596- */
597597- min: number
598598- /**
599599- * the maximum value in the samples
600600- */
601601- max: number
602602-603603- /**
604604- * the number of operations per second
605605- */
606606- hz: number
607607-608608- /**
609609- * how long each operation takes (ms)
610610- */
611611- period: number
612612-613613- /**
614614- * task samples of each task iteration time (ms)
615615- */
616616- samples: number[]
617617-618618- /**
619619- * samples mean/average (estimate of the population mean)
620620- */
621621- mean: number
622622-623623- /**
624624- * samples variance (estimate of the population variance)
625625- */
626626- variance: number
627627-628628- /**
629629- * samples standard deviation (estimate of the population standard deviation)
630630- */
631631- sd: number
632632-633633- /**
634634- * standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean)
635635- */
636636- sem: number
637637-638638- /**
639639- * degrees of freedom
640640- */
641641- df: number
642642-643643- /**
644644- * critical value of the samples
645645- */
646646- critical: number
647647-648648- /**
649649- * margin of error
650650- */
651651- moe: number
652652-653653- /**
654654- * relative margin of error
655655- */
656656- rme: number
657657-658658- /**
659659- * median absolute deviation
660660- */
661661- mad: number
662662-663663- /**
664664- * p50/median percentile
665665- */
666666- p50: number
667667-668668- /**
669669- * p75 percentile
670670- */
671671- p75: number
672672-673673- /**
674674- * p99 percentile
675675- */
676676- p99: number
677677-678678- /**
679679- * p995 percentile
680680- */
681681- p995: number
682682-683683- /**
684684- * p999 percentile
685685- */
686686- p999: number
687687-}
688688-```
689689-690690-### bench.skip
691691-692692-- **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`
693693-694694-You can use `bench.skip` syntax to skip running certain benchmarks.
695695-696696-```ts
697697-import { bench } from 'vitest'
698698-699699-bench.skip('normal sorting', () => {
700700- const x = [1, 5, 4, 2, 3]
701701- x.sort((a, b) => {
702702- return a - b
703703- })
704704-})
705705-```
706706-707707-### bench.only
708708-709709-- **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`
710710-711711-Use `bench.only` to only run certain benchmarks in a given suite. This is useful when debugging.
712712-713713-```ts
714714-import { bench } from 'vitest'
715715-716716-bench.only('normal sorting', () => {
717717- const x = [1, 5, 4, 2, 3]
718718- x.sort((a, b) => {
719719- return a - b
720720- })
721721-})
722722-```
723723-724724-### bench.todo
725725-726726-- **Type:** `(name: string | Function) => void`
727727-728728-Use `bench.todo` to stub benchmarks to be implemented later.
729729-730730-```ts
731731-import { bench } from 'vitest'
732732-733733-bench.todo('unimplemented test')
734734-```
735735-736736-## describe
737737-738738-When you use `test` or `bench` in the top level of file, they are collected as part of the implicit suite for it. Using `describe` you can define a new suite in the current context, as a set of related tests or benchmarks and other nested suites. A suite lets you organize your tests and benchmarks so reports are more clear.
739739-740740-```ts
741741-// basic.spec.ts
742742-// organizing tests
743743-744744-import { describe, expect, test } from 'vitest'
745745-746746-const person = {
747747- isActive: true,
748748- age: 32,
749749-}
750750-751751-describe('person', () => {
752752- test('person is defined', () => {
753753- expect(person).toBeDefined()
754754- })
755755-756756- test('is active', () => {
757757- expect(person.isActive).toBeTruthy()
758758- })
759759-760760- test('age limit', () => {
761761- expect(person.age).toBeLessThanOrEqual(32)
762762- })
763763-})
764764-```
765765-766766-```ts
767767-// basic.bench.ts
768768-// organizing benchmarks
769769-770770-import { bench, describe } from 'vitest'
771771-772772-describe('sort', () => {
773773- bench('normal', () => {
774774- const x = [1, 5, 4, 2, 3]
775775- x.sort((a, b) => {
776776- return a - b
777777- })
778778- })
779779-780780- bench('reverse', () => {
781781- const x = [1, 5, 4, 2, 3]
782782- x.reverse().sort((a, b) => {
783783- return a - b
784784- })
785785- })
786786-})
787787-```
788788-789789-You can also nest describe blocks if you have a hierarchy of tests or benchmarks:
790790-791791-```ts
792792-import { describe, expect, test } from 'vitest'
793793-794794-function numberToCurrency(value: number | string) {
795795- if (typeof value !== 'number') {
796796- throw new TypeError('Value must be a number')
797797- }
798798-799799- return value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
800800-}
801801-802802-describe('numberToCurrency', () => {
803803- describe('given an invalid number', () => {
804804- test('composed of non-numbers to throw error', () => {
805805- expect(() => numberToCurrency('abc')).toThrowError()
806806- })
807807- })
808808-809809- describe('given a valid number', () => {
810810- test('returns the correct currency format', () => {
811811- expect(numberToCurrency(10000)).toBe('10,000.00')
812812- })
813813- })
814814-})
815815-```
816816-817817-### describe.skip
818818-819819-- **Alias:** `suite.skip`
820820-821821-Use `describe.skip` in a suite to avoid running a particular describe block.
822822-823823-```ts
824824-import { assert, describe, test } from 'vitest'
825825-826826-describe.skip('skipped suite', () => {
827827- test('sqrt', () => {
828828- // Suite skipped, no error
829829- assert.equal(Math.sqrt(4), 3)
830830- })
831831-})
832832-```
833833-834834-### describe.skipIf
835835-836836-- **Alias:** `suite.skipIf`
837837-838838-In some cases, you might run suites multiple times with different environments, and some of the suites might be environment-specific. Instead of wrapping the suite with `if`, you can use `describe.skipIf` to skip the suite whenever the condition is truthy.
839839-840840-```ts
841841-import { describe, test } from 'vitest'
842842-843843-const isDev = process.env.NODE_ENV === 'development'
844844-845845-describe.skipIf(isDev)('prod only test suite', () => {
846846- // this test suite only runs in production
847847-})
848848-```
849849-850850-::: warning
851851-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
852852-:::
853853-854854-### describe.runIf
855855-856856-- **Alias:** `suite.runIf`
857857-858858-Opposite of [describe.skipIf](#describe-skipif).
859859-860860-```ts
861861-import { assert, describe, test } from 'vitest'
862862-863863-const isDev = process.env.NODE_ENV === 'development'
864864-865865-describe.runIf(isDev)('dev only test suite', () => {
866866- // this test suite only runs in development
867867-})
868868-```
869869-870870-::: warning
871871-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
872872-:::
873873-874874-### describe.only
875875-876876-- **Type:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void`
877877-878878-Use `describe.only` to only run certain suites
879879-880880-```ts
881881-import { assert, describe, test } from 'vitest'
882882-883883-// Only this suite (and others marked with only) are run
884884-describe.only('suite', () => {
885885- test('sqrt', () => {
886886- assert.equal(Math.sqrt(4), 3)
887887- })
888888-})
889889-890890-describe('other suite', () => {
891891- // ... will be skipped
892892-})
893893-```
894894-895895-Sometimes it is very useful to run `only` tests in a certain file, ignoring all other tests from the whole test suite, which pollute the output.
896896-897897-In order to do that run `vitest` with specific file containing the tests in question.
898898-```
899899-# vitest interesting.test.ts
900900-```
901901-902902-### describe.concurrent
903903-904904-- **Alias:** `suite.concurrent`
905905-906906-`describe.concurrent` runs all inner suites and tests in parallel
907907-908908-```ts
909909-import { describe, test } from 'vitest'
910910-911911-// All suites and tests within this suite will be run in parallel
912912-describe.concurrent('suite', () => {
913913- test('concurrent test 1', async () => { /* ... */ })
914914- describe('concurrent suite 2', async () => {
915915- test('concurrent test inner 1', async () => { /* ... */ })
916916- test('concurrent test inner 2', async () => { /* ... */ })
917917- })
918918- test.concurrent('concurrent test 3', async () => { /* ... */ })
919919-})
920920-```
921921-922922-`.skip`, `.only`, and `.todo` works with concurrent suites. All the following combinations are valid:
923923-924924-```ts
925925-describe.concurrent(/* ... */)
926926-describe.skip.concurrent(/* ... */) // or describe.concurrent.skip(/* ... */)
927927-describe.only.concurrent(/* ... */) // or describe.concurrent.only(/* ... */)
928928-describe.todo.concurrent(/* ... */) // or describe.concurrent.todo(/* ... */)
929929-```
930930-931931-When running concurrent tests, Snapshots and Assertions must use `expect` from the local [Test Context](/guide/test-context) to ensure the right test is detected.
932932-933933-```ts
934934-describe.concurrent('suite', () => {
935935- test('concurrent test 1', async ({ expect }) => {
936936- expect(foo).toMatchSnapshot()
937937- })
938938- test('concurrent test 2', async ({ expect }) => {
939939- expect(foo).toMatchSnapshot()
940940- })
941941-})
942942-```
943943-944944-::: warning
945945-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
946946-:::
947947-948948-### describe.sequential
949949-950950-- **Alias:** `suite.sequential`
951951-952952-`describe.sequential` in a suite marks every test as sequential. This is useful if you want to run tests in sequence within `describe.concurrent` or with the `--sequence.concurrent` command option.
953953-954954-```ts
955955-import { describe, test } from 'vitest'
956956-957957-describe.concurrent('suite', () => {
958958- test('concurrent test 1', async () => { /* ... */ })
959959- test('concurrent test 2', async () => { /* ... */ })
960960-961961- describe.sequential('', () => {
962962- test('sequential test 1', async () => { /* ... */ })
963963- test('sequential test 2', async () => { /* ... */ })
964964- })
965965-})
966966-```
967967-968968-### describe.shuffle
969969-970970-- **Alias:** `suite.shuffle`
971971-972972-Vitest provides a way to run all tests in random order via CLI flag [`--sequence.shuffle`](/guide/cli) or config option [`sequence.shuffle`](/config/#sequence-shuffle), but if you want to have only part of your test suite to run tests in random order, you can mark it with this flag.
973973-974974-```ts
975975-import { describe, test } from 'vitest'
976976-977977-// or describe('suite', { shuffle: true }, ...)
978978-describe.shuffle('suite', () => {
979979- test('random test 1', async () => { /* ... */ })
980980- test('random test 2', async () => { /* ... */ })
981981- test('random test 3', async () => { /* ... */ })
982982-983983- // `shuffle` is inherited
984984- describe('still random', () => {
985985- test('random 4.1', async () => { /* ... */ })
986986- test('random 4.2', async () => { /* ... */ })
987987- })
988988-989989- // disable shuffle inside
990990- describe('not random', { shuffle: false }, () => {
991991- test('in order 5.1', async () => { /* ... */ })
992992- test('in order 5.2', async () => { /* ... */ })
993993- })
994994-})
995995-// order depends on sequence.seed option in config (Date.now() by default)
996996-```
997997-998998-`.skip`, `.only`, and `.todo` works with random suites.
999999-10001000-::: warning
10011001-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
10021002-:::
10031003-10041004-### describe.todo
10051005-10061006-- **Alias:** `suite.todo`
10071007-10081008-Use `describe.todo` to stub suites to be implemented later. An entry will be shown in the report for the tests so you know how many tests you still need to implement.
10091009-10101010-```ts
10111011-// An entry will be shown in the report for this suite
10121012-describe.todo('unimplemented suite')
10131013-```
10141014-10151015-### describe.each
10161016-10171017-- **Alias:** `suite.each`
10181018-10191019-::: tip
10201020-While `describe.each` is provided for Jest compatibility,
10211021-Vitest also has [`describe.for`](#describe-for) which simplifies argument types and aligns with [`test.for`](#test-for).
10221022-:::
10231023-10241024-Use `describe.each` if you have more than one test that depends on the same data.
10251025-10261026-```ts
10271027-import { describe, expect, test } from 'vitest'
10281028-10291029-describe.each([
10301030- { a: 1, b: 1, expected: 2 },
10311031- { a: 1, b: 2, expected: 3 },
10321032- { a: 2, b: 1, expected: 3 },
10331033-])('describe object add($a, $b)', ({ a, b, expected }) => {
10341034- test(`returns ${expected}`, () => {
10351035- expect(a + b).toBe(expected)
10361036- })
10371037-10381038- test(`returned value not be greater than ${expected}`, () => {
10391039- expect(a + b).not.toBeGreaterThan(expected)
10401040- })
10411041-10421042- test(`returned value not be less than ${expected}`, () => {
10431043- expect(a + b).not.toBeLessThan(expected)
10441044- })
10451045-})
10461046-```
10471047-10481048-* First row should be column names, separated by `|`;
10491049-* One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
10501050-10511051-```ts
10521052-import { describe, expect, test } from 'vitest'
10531053-10541054-describe.each`
10551055- a | b | expected
10561056- ${1} | ${1} | ${2}
10571057- ${'a'} | ${'b'} | ${'ab'}
10581058- ${[]} | ${'b'} | ${'b'}
10591059- ${{}} | ${'b'} | ${'[object Object]b'}
10601060- ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
10611061-`('describe template string add($a, $b)', ({ a, b, expected }) => {
10621062- test(`returns ${expected}`, () => {
10631063- expect(a + b).toBe(expected)
10641064- })
10651065-})
10661066-```
10671067-10681068-::: warning
10691069-You cannot use this syntax when using Vitest as [type checker](/guide/testing-types).
10701070-:::
10711071-10721072-### describe.for
10731073-10741074-- **Alias:** `suite.for`
10751075-10761076-The difference from `describe.each` is how array case is provided in the arguments.
10771077-Other non array case (including template string usage) works exactly same.
10781078-10791079-```ts
10801080-// `each` spreads array case
10811081-describe.each([
10821082- [1, 1, 2],
10831083- [1, 2, 3],
10841084- [2, 1, 3],
10851085-])('add(%i, %i) -> %i', (a, b, expected) => { // [!code --]
10861086- test('test', () => {
10871087- expect(a + b).toBe(expected)
10881088- })
10891089-})
10901090-10911091-// `for` doesn't spread array case
10921092-describe.for([
10931093- [1, 1, 2],
10941094- [1, 2, 3],
10951095- [2, 1, 3],
10961096-])('add(%i, %i) -> %i', ([a, b, expected]) => { // [!code ++]
10971097- test('test', () => {
10981098- expect(a + b).toBe(expected)
10991099- })
11001100-})
11011101-```
11021102-11031103-## Setup and Teardown
11041104-11051105-These functions allow you to hook into the life cycle of tests to avoid repeating setup and teardown code. They apply to the current context: the file if they are used at the top-level or the current suite if they are inside a `describe` block. These hooks are not called, when you are running Vitest as a type checker.
11061106-11071107-### beforeEach
11081108-11091109-- **Type:** `beforeEach(fn: () => Awaitable<void>, timeout?: number)`
11101110-11111111-Register a callback to be called before each of the tests in the current context runs.
11121112-If the function returns a promise, Vitest waits until the promise resolve before running the test.
11131113-11141114-Optionally, you can pass a timeout (in milliseconds) defining how long to wait before terminating. The default is 5 seconds.
11151115-11161116-```ts
11171117-import { beforeEach } from 'vitest'
11181118-11191119-beforeEach(async () => {
11201120- // Clear mocks and add some testing data before each test run
11211121- await stopMocking()
11221122- await addUser({ name: 'John' })
11231123-})
11241124-```
11251125-11261126-Here, the `beforeEach` ensures that user is added for each test.
11271127-11281128-`beforeEach` also accepts an optional cleanup function (equivalent to `afterEach`).
11291129-11301130-```ts
11311131-import { beforeEach } from 'vitest'
11321132-11331133-beforeEach(async () => {
11341134- // called once before each test run
11351135- await prepareSomething()
11361136-11371137- // clean up function, called once after each test run
11381138- return async () => {
11391139- await resetSomething()
11401140- }
11411141-})
11421142-```
11431143-11441144-### afterEach
11451145-11461146-- **Type:** `afterEach(fn: () => Awaitable<void>, timeout?: number)`
11471147-11481148-Register a callback to be called after each one of the tests in the current context completes.
11491149-If the function returns a promise, Vitest waits until the promise resolve before continuing.
11501150-11511151-Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds.
11521152-11531153-```ts
11541154-import { afterEach } from 'vitest'
11551155-11561156-afterEach(async () => {
11571157- await clearTestingData() // clear testing data after each test run
11581158-})
11591159-```
11601160-11611161-Here, the `afterEach` ensures that testing data is cleared after each test runs.
11621162-11631163-::: tip
11641164-You can also use [`onTestFinished`](#ontestfinished) during the test execution to cleanup any state after the test has finished running.
11651165-:::
11661166-11671167-### beforeAll
11681168-11691169-- **Type:** `beforeAll(fn: () => Awaitable<void>, timeout?: number)`
11701170-11711171-Register a callback to be called once before starting to run all tests in the current context.
11721172-If the function returns a promise, Vitest waits until the promise resolve before running tests.
11731173-11741174-Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds.
11751175-11761176-```ts
11771177-import { beforeAll } from 'vitest'
11781178-11791179-beforeAll(async () => {
11801180- await startMocking() // called once before all tests run
11811181-})
11821182-```
11831183-11841184-Here the `beforeAll` ensures that the mock data is set up before tests run.
11851185-11861186-`beforeAll` also accepts an optional cleanup function (equivalent to `afterAll`).
11871187-11881188-```ts
11891189-import { beforeAll } from 'vitest'
11901190-11911191-beforeAll(async () => {
11921192- // called once before all tests run
11931193- await startMocking()
11941194-11951195- // clean up function, called once after all tests run
11961196- return async () => {
11971197- await stopMocking()
11981198- }
11991199-})
12001200-```
12011201-12021202-### afterAll
12031203-12041204-- **Type:** `afterAll(fn: () => Awaitable<void>, timeout?: number)`
12051205-12061206-Register a callback to be called once after all tests have run in the current context.
12071207-If the function returns a promise, Vitest waits until the promise resolve before continuing.
12081208-12091209-Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds.
12101210-12111211-```ts
12121212-import { afterAll } from 'vitest'
12131213-12141214-afterAll(async () => {
12151215- await stopMocking() // this method is called after all tests run
12161216-})
12171217-```
12181218-12191219-Here the `afterAll` ensures that `stopMocking` method is called after all tests run.
12201220-12211221-## Test Hooks
12221222-12231223-Vitest provides a few hooks that you can call _during_ the test execution to cleanup the state when the test has finished running.
12241224-12251225-::: warning
12261226-These hooks will throw an error if they are called outside of the test body.
12271227-:::
12281228-12291229-### onTestFinished {#ontestfinished}
12301230-12311231-This hook is always called after the test has finished running. It is called after `afterEach` hooks since they can influence the test result. It receives an `ExtendedContext` object like `beforeEach` and `afterEach`.
12321232-12331233-```ts {1,5}
12341234-import { onTestFinished, test } from 'vitest'
12351235-12361236-test('performs a query', () => {
12371237- const db = connectDb()
12381238- onTestFinished(() => db.close())
12391239- db.query('SELECT * FROM users')
12401240-})
12411241-```
12421242-12431243-::: warning
12441244-If you are running tests concurrently, you should always use `onTestFinished` hook from the test context since Vitest doesn't track concurrent tests in global hooks:
12451245-12461246-```ts {3,5}
12471247-import { test } from 'vitest'
12481248-12491249-test.concurrent('performs a query', ({ onTestFinished }) => {
12501250- const db = connectDb()
12511251- onTestFinished(() => db.close())
12521252- db.query('SELECT * FROM users')
12531253-})
12541254-```
12551255-:::
12561256-12571257-This hook is particularly useful when creating reusable logic:
12581258-12591259-```ts
12601260-// this can be in a separate file
12611261-function getTestDb() {
12621262- const db = connectMockedDb()
12631263- onTestFinished(() => db.close())
12641264- return db
12651265-}
12661266-12671267-test('performs a user query', async () => {
12681268- const db = getTestDb()
12691269- expect(
12701270- await db.query('SELECT * from users').perform()
12711271- ).toEqual([])
12721272-})
12731273-12741274-test('performs an organization query', async () => {
12751275- const db = getTestDb()
12761276- expect(
12771277- await db.query('SELECT * from organizations').perform()
12781278- ).toEqual([])
12791279-})
12801280-```
12811281-12821282-::: tip
12831283-This hook is always called in reverse order and is not affected by [`sequence.hooks`](/config/#sequence-hooks) option.
12841284-:::
12851285-12861286-### onTestFailed
12871287-12881288-This hook is called only after the test has failed. It is called after `afterEach` hooks since they can influence the test result. It receives an `ExtendedContext` object like `beforeEach` and `afterEach`. This hook is useful for debugging.
12891289-12901290-```ts {1,5-7}
12911291-import { onTestFailed, test } from 'vitest'
12921292-12931293-test('performs a query', () => {
12941294- const db = connectDb()
12951295- onTestFailed(({ task }) => {
12961296- console.log(task.result.errors)
12971297- })
12981298- db.query('SELECT * FROM users')
12991299-})
13001300-```
13011301-13021302-::: warning
13031303-If you are running tests concurrently, you should always use `onTestFailed` hook from the test context since Vitest doesn't track concurrent tests in global hooks:
13041304-13051305-```ts {3,5-7}
13061306-import { test } from 'vitest'
13071307-13081308-test.concurrent('performs a query', ({ onTestFailed }) => {
13091309- const db = connectDb()
13101310- onTestFailed(({ task }) => {
13111311- console.log(task.result.errors)
13121312- })
13131313- db.query('SELECT * FROM users')
13141314-})
13151315-```
13161316-:::
+857
docs/api/test.md
···11+---
22+outline: deep
33+---
44+55+# Test
66+77+- **Alias:** `it`
88+99+```ts
1010+function test(
1111+ name: string | Function,
1212+ body?: () => unknown,
1313+ timeout?: number
1414+): void
1515+function test(
1616+ name: string | Function,
1717+ options: TestOptions,
1818+ body?: () => unknown,
1919+): void
2020+```
2121+2222+`test` or `it` defines a set of related expectations. It receives the test name and a function that holds the expectations to test.
2323+2424+Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating, or a set of [additional options](#test-options). The default timeout is 5 seconds, and can be configured globally with [`testTimeout`](/config/testtimeout).
2525+2626+```ts
2727+import { expect, test } from 'vitest'
2828+2929+test('should work as expected', () => {
3030+ expect(Math.sqrt(4)).toBe(2)
3131+})
3232+```
3333+3434+::: warning
3535+If the first argument is a function, its `name` property will be used as the name of the test. The function itself will not be called.
3636+3737+If test body is not provided, the test is marked as `todo`.
3838+:::
3939+4040+When a test function returns a promise, the runner will wait until it is resolved to collect async expectations. If the promise is rejected, the test will fail.
4141+4242+::: tip
4343+In Jest, `TestFunction` can also be of type `(done: DoneCallback) => void`. If this form is used, the test will not be concluded until `done` is called. You can achieve the same using an `async` function, see the [Migration guide Done Callback section](/guide/migration#done-callback).
4444+:::
4545+4646+## Test Options
4747+4848+You can define boolean options by chaining properties on a function:
4949+5050+```ts
5151+import { test } from 'vitest'
5252+5353+test.skip('skipped test', () => {
5454+ // some logic that fails right now
5555+})
5656+5757+test.concurrent.skip('skipped concurrent test', () => {
5858+ // some logic that fails right now
5959+})
6060+```
6161+6262+But you can also provide an object as a second argument instead:
6363+6464+```ts
6565+import { test } from 'vitest'
6666+6767+test('skipped test', { skip: true }, () => {
6868+ // some logic that fails right now
6969+})
7070+7171+test('skipped concurrent test', { skip: true, concurrent: true }, () => {
7272+ // some logic that fails right now
7373+})
7474+```
7575+7676+They both work in exactly the same way. To use either one is purely a stylistic choice.
7777+7878+### timeout
7979+8080+- **Type:** `number`
8181+- **Default:** `5_000` (configured by [`testTimeout`](/config/testtimeout))
8282+8383+Test timeout in milliseconds.
8484+8585+::: warning
8686+Note that if you are providing timeout as the last argument, you cannot use options anymore:
8787+8888+```ts
8989+import { test } from 'vitest'
9090+9191+// ✅ this works
9292+test.skip('heavy test', () => {
9393+ // ...
9494+}, 10_000)
9595+9696+// ❌ this doesn't work
9797+test('heavy test', { skip: true }, () => {
9898+ // ...
9999+}, 10_000)
100100+```
101101+102102+However, you can provide a timeout inside the object:
103103+104104+```ts
105105+import { test } from 'vitest'
106106+107107+// ✅ this works
108108+test('heavy test', { skip: true, timeout: 10_000 }, () => {
109109+ // ...
110110+})
111111+```
112112+:::
113113+114114+### retry
115115+116116+- **Default:** `0` (configured by [`retry`](/config/retry))
117117+- **Type:**
118118+119119+```ts
120120+type Retry = number | {
121121+ /**
122122+ * The number of times to retry the test if it fails.
123123+ * @default 0
124124+ */
125125+ count?: number
126126+ /**
127127+ * Delay in milliseconds between retry attempts.
128128+ * @default 0
129129+ */
130130+ delay?: number
131131+ /**
132132+ * Condition to determine if a test should be retried based on the error.
133133+ * - If a RegExp, it is tested against the error message
134134+ * - If a function, called with the TestError object; return true to retry
135135+ *
136136+ * NOTE: Functions can only be used in test files, not in vitest.config.ts,
137137+ * because the configuration is serialized when passed to worker threads.
138138+ *
139139+ * @default undefined (retry on all errors)
140140+ */
141141+ condition?: RegExp | ((error: TestError) => boolean)
142142+}
143143+```
144144+145145+Retry configuration for the test. If a number, specifies how many times to retry. If an object, allows fine-grained retry control.
146146+147147+Note that the object configuration is available only since Vitest 4.1.
148148+149149+### repeats
150150+151151+- **Type:** `number`
152152+- **Default:** `0`
153153+154154+How many times the test will run again. If set to `0` (the default), the test will run only one time.
155155+156156+This can be useful for debugging flaky tests.
157157+158158+### tags <Version>4.1.0</Version> {#tags}
159159+160160+- **Type:** `string[]`
161161+- **Default:** `[]`
162162+163163+Custom user [tags](/guide/test-tags). If the tag is not specified in the [configuration](/config/tags), the test will fail before it starts, unless [`strictTags`](/config/stricttags) is disabled manually.
164164+165165+```ts
166166+import { it } from 'vitest'
167167+168168+it('user returns data from db', { tags: ['db', 'flaky'] }, () => {
169169+ // ...
170170+})
171171+```
172172+173173+### concurrent
174174+175175+- **Type:** `boolean`
176176+- **Default:** `false` (configured by [`sequence.concurrent`](/config/sequence#sequence-concurrent))
177177+- **Alias:** [`test.concurrent`](#test-concurrent)
178178+179179+Whether this test run concurrently with other concurrent tests in the suite.
180180+181181+### sequential
182182+183183+- **Type:** `boolean`
184184+- **Default:** `true`
185185+- **Alias:** [`test.sequential`](#test-sequential)
186186+187187+Whether tests run sequentially. When both `concurrent` and `sequential` are specified, `concurrent` takes precendence.
188188+189189+### skip
190190+191191+- **Type:** `boolean`
192192+- **Default:** `false`
193193+- **Alias:** [`test.skip`](#test-skip)
194194+195195+Whether the test should be skipped.
196196+197197+### only
198198+199199+- **Type:** `boolean`
200200+- **Default:** `false`
201201+- **Alias:** [`test.only`](#test-only)
202202+203203+Should this test be the only one running in a suite.
204204+205205+### todo
206206+207207+- **Type:** `boolean`
208208+- **Default:** `false`
209209+- **Alias:** [`test.todo`](#test-todo)
210210+211211+Whether the test should be skipped and marked as a todo.
212212+213213+### fails
214214+215215+- **Type:** `boolean`
216216+- **Default:** `false`
217217+- **Alias:** [`test.fails`](#test-fails)
218218+219219+Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail.
220220+221221+## test.extend
222222+223223+- **Alias:** `it.extend`
224224+225225+Use `test.extend` to extend the test context with custom fixtures. This will return a new `test` and it's also extendable, so you can compose more fixtures or override existing ones by extending it as you need. See [Extend Test Context](/guide/test-context.html#test-extend) for more information.
226226+227227+```ts
228228+import { test as baseTest, expect } from 'vitest'
229229+230230+const todos = []
231231+const archive = []
232232+233233+const test = baseTest.extend({
234234+ todos: async ({ task }, use) => {
235235+ todos.push(1, 2, 3)
236236+ await use(todos)
237237+ todos.length = 0
238238+ },
239239+ archive,
240240+})
241241+242242+test('add item', ({ todos }) => {
243243+ expect(todos.length).toBe(3)
244244+245245+ todos.push(4)
246246+ expect(todos.length).toBe(4)
247247+})
248248+```
249249+250250+## test.skip
251251+252252+- **Alias:** `it.skip`
253253+254254+If you want to skip running certain tests, but you don't want to delete the code due to any reason, you can use `test.skip` to avoid running them.
255255+256256+```ts
257257+import { assert, test } from 'vitest'
258258+259259+test.skip('skipped test', () => {
260260+ // Test skipped, no error
261261+ assert.equal(Math.sqrt(4), 3)
262262+})
263263+```
264264+265265+You can also skip test by calling `skip` on its [context](/guide/test-context) dynamically:
266266+267267+```ts
268268+import { assert, test } from 'vitest'
269269+270270+test('skipped test', (context) => {
271271+ context.skip()
272272+ // Test skipped, no error
273273+ assert.equal(Math.sqrt(4), 3)
274274+})
275275+```
276276+277277+If the condition is unknown, you can provide it to the `skip` method as the first arguments:
278278+279279+```ts
280280+import { assert, test } from 'vitest'
281281+282282+test('skipped test', (context) => {
283283+ context.skip(Math.random() < 0.5, 'optional message')
284284+ // Test skipped, no error
285285+ assert.equal(Math.sqrt(4), 3)
286286+})
287287+```
288288+289289+## test.skipIf
290290+291291+- **Alias:** `it.skipIf`
292292+293293+In some cases you might run tests multiple times with different environments, and some of the tests might be environment-specific. Instead of wrapping the test code with `if`, you can use `test.skipIf` to skip the test whenever the condition is truthy.
294294+295295+```ts
296296+import { assert, test } from 'vitest'
297297+298298+const isDev = process.env.NODE_ENV === 'development'
299299+300300+test.skipIf(isDev)('prod only test', () => {
301301+ // this test only runs in production
302302+})
303303+```
304304+305305+## test.runIf
306306+307307+- **Alias:** `it.runIf`
308308+309309+Opposite of [test.skipIf](#test-skipif).
310310+311311+```ts
312312+import { assert, test } from 'vitest'
313313+314314+const isDev = process.env.NODE_ENV === 'development'
315315+316316+test.runIf(isDev)('dev only test', () => {
317317+ // this test only runs in development
318318+})
319319+```
320320+321321+## test.only
322322+323323+- **Alias:** `it.only`
324324+325325+Use `test.only` to only run certain tests in a given suite. This is useful when debugging.
326326+327327+```ts
328328+import { assert, test } from 'vitest'
329329+330330+test.only('test', () => {
331331+ // Only this test (and others marked with only) are run
332332+ assert.equal(Math.sqrt(4), 2)
333333+})
334334+```
335335+336336+Sometimes it is very useful to run `only` tests in a certain file, ignoring all other tests from the whole test suite, which pollute the output.
337337+338338+In order to do that, run `vitest` with specific file containing the tests in question:
339339+340340+```shell
341341+vitest interesting.test.ts
342342+```
343343+344344+::: warning
345345+Vitest detects when tests are running in CI and will throw an error if any test has `only` flag. You can configure this behaviour via [`allowOnly`](/config/allowonly) option.
346346+:::
347347+348348+## test.concurrent
349349+350350+- **Alias:** `it.concurrent`
351351+352352+`test.concurrent` marks consecutive tests to be run in parallel. It receives the test name, an async function with the tests to collect, and an optional timeout (in milliseconds).
353353+354354+```ts
355355+import { describe, test } from 'vitest'
356356+357357+// The two tests marked with concurrent will be run in parallel
358358+describe('suite', () => {
359359+ test('serial test', async () => { /* ... */ })
360360+ test.concurrent('concurrent test 1', async () => { /* ... */ })
361361+ test.concurrent('concurrent test 2', async () => { /* ... */ })
362362+})
363363+```
364364+365365+`test.skip`, `test.only`, and `test.todo` works with concurrent tests. All the following combinations are valid:
366366+367367+```ts
368368+test.concurrent(/* ... */)
369369+test.skip.concurrent(/* ... */) // or test.concurrent.skip(/* ... */)
370370+test.only.concurrent(/* ... */) // or test.concurrent.only(/* ... */)
371371+test.todo.concurrent(/* ... */) // or test.concurrent.todo(/* ... */)
372372+```
373373+374374+When running concurrent tests, Snapshots and Assertions must use `expect` from the local [Test Context](/guide/test-context.md) to ensure the right test is detected.
375375+376376+```ts
377377+test.concurrent('test 1', async ({ expect }) => {
378378+ expect(foo).toMatchSnapshot()
379379+})
380380+test.concurrent('test 2', async ({ expect }) => {
381381+ expect(foo).toMatchSnapshot()
382382+})
383383+```
384384+385385+Note that if tests are synchronous, Vitest will still run them sequentially.
386386+387387+## test.sequential
388388+389389+- **Alias:** `it.sequential`
390390+391391+`test.sequential` marks a test as sequential. This is useful if you want to run tests in sequence within `describe.concurrent` or with the `--sequence.concurrent` command option.
392392+393393+```ts
394394+import { describe, test } from 'vitest'
395395+396396+// with config option { sequence: { concurrent: true } }
397397+test('concurrent test 1', async () => { /* ... */ })
398398+test('concurrent test 2', async () => { /* ... */ })
399399+400400+test.sequential('sequential test 1', async () => { /* ... */ })
401401+test.sequential('sequential test 2', async () => { /* ... */ })
402402+403403+// within concurrent suite
404404+describe.concurrent('suite', () => {
405405+ test('concurrent test 1', async () => { /* ... */ })
406406+ test('concurrent test 2', async () => { /* ... */ })
407407+408408+ test.sequential('sequential test 1', async () => { /* ... */ })
409409+ test.sequential('sequential test 2', async () => { /* ... */ })
410410+})
411411+```
412412+413413+## test.todo
414414+415415+- **Alias:** `it.todo`
416416+417417+Use `test.todo` to stub tests to be implemented later. An entry will be shown in the report for the tests so you know how many tests you still need to implement.
418418+419419+```ts
420420+// An entry will be shown in the report for this test
421421+test.todo('unimplemented test', () => {
422422+ // failing implementation...
423423+})
424424+```
425425+426426+::: tip
427427+Vitest will automatically mark test as `todo` if test has no body.
428428+:::
429429+430430+## test.fails
431431+432432+- **Alias:** `it.fails`
433433+434434+Use `test.fails` to indicate that an assertion will fail explicitly.
435435+436436+```ts
437437+import { expect, test } from 'vitest'
438438+439439+test.fails('repro #1234', () => {
440440+ expect(add(1, 2)).toBe(4)
441441+})
442442+```
443443+444444+This flag is useful to track difference in behaviour of your library over time. For example, you can define a failing test without fixing the issue yet due to time constraints. Tests marked with `fails` are tracked in the test summary since Vitest 4.1.
445445+446446+## test.each
447447+448448+- **Alias:** `it.each`
449449+450450+::: tip
451451+While `test.each` is provided for Jest compatibility,
452452+Vitest also has [`test.for`](#test-for) with an additional feature to integrate [`TestContext`](/guide/test-context).
453453+:::
454454+455455+Use `test.each` when you need to run the same test with different variables.
456456+You can inject parameters with [printf formatting](https://nodejs.org/api/util.html#util_util_format_format_args) in the test name in the order of the test function parameters.
457457+458458+- `%s`: string
459459+- `%d`: number
460460+- `%i`: integer
461461+- `%f`: floating point value
462462+- `%j`: json
463463+- `%o`: object
464464+- `%#`: 0-based index of the test case
465465+- `%$`: 1-based index of the test case
466466+- `%%`: single percent sign ('%')
467467+468468+```ts
469469+import { expect, test } from 'vitest'
470470+471471+test.each([
472472+ [1, 1, 2],
473473+ [1, 2, 3],
474474+ [2, 1, 3],
475475+])('add(%i, %i) -> %i', (a, b, expected) => {
476476+ expect(a + b).toBe(expected)
477477+})
478478+479479+// this will return
480480+// ✓ add(1, 1) -> 2
481481+// ✓ add(1, 2) -> 3
482482+// ✓ add(2, 1) -> 3
483483+```
484484+485485+You can also access object properties and array elements with `$` prefix:
486486+487487+```ts
488488+test.each([
489489+ { a: 1, b: 1, expected: 2 },
490490+ { a: 1, b: 2, expected: 3 },
491491+ { a: 2, b: 1, expected: 3 },
492492+])('add($a, $b) -> $expected', ({ a, b, expected }) => {
493493+ expect(a + b).toBe(expected)
494494+})
495495+496496+// this will return
497497+// ✓ add(1, 1) -> 2
498498+// ✓ add(1, 2) -> 3
499499+// ✓ add(2, 1) -> 3
500500+501501+test.each([
502502+ [1, 1, 2],
503503+ [1, 2, 3],
504504+ [2, 1, 3],
505505+])('add($0, $1) -> $2', (a, b, expected) => {
506506+ expect(a + b).toBe(expected)
507507+})
508508+509509+// this will return
510510+// ✓ add(1, 1) -> 2
511511+// ✓ add(1, 2) -> 3
512512+// ✓ add(2, 1) -> 3
513513+```
514514+515515+You can also access Object attributes with `.`, if you are using objects as arguments:
516516+517517+ ```ts
518518+ test.each`
519519+ a | b | expected
520520+ ${{ val: 1 }} | ${'b'} | ${'1b'}
521521+ ${{ val: 2 }} | ${'b'} | ${'2b'}
522522+ ${{ val: 3 }} | ${'b'} | ${'3b'}
523523+ `('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
524524+ expect(a.val + b).toBe(expected)
525525+ })
526526+527527+ // this will return
528528+ // ✓ add(1, b) -> 1b
529529+ // ✓ add(2, b) -> 2b
530530+ // ✓ add(3, b) -> 3b
531531+ ```
532532+533533+* First row should be column names, separated by `|`;
534534+* One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
535535+536536+```ts
537537+import { expect, test } from 'vitest'
538538+539539+test.each`
540540+ a | b | expected
541541+ ${1} | ${1} | ${2}
542542+ ${'a'} | ${'b'} | ${'ab'}
543543+ ${[]} | ${'b'} | ${'b'}
544544+ ${{}} | ${'b'} | ${'[object Object]b'}
545545+ ${{ asd: 1 }} | ${'b'} | ${'[object Object]b'}
546546+`('returns $expected when $a is added $b', ({ a, b, expected }) => {
547547+ expect(a + b).toBe(expected)
548548+})
549549+```
550550+551551+::: tip
552552+Vitest processes `$values` with Chai `format` method. If the value is too truncated, you can increase [chaiConfig.truncateThreshold](/config/#chaiconfig-truncatethreshold) in your config file.
553553+:::
554554+555555+## test.for
556556+557557+- **Alias:** `it.for`
558558+559559+Alternative to `test.each` to provide [`TestContext`](/guide/test-context).
560560+561561+The difference from `test.each` lies in how arrays are provided in the arguments.
562562+Non-array arguments to `test.for` (including template string usage) work exactly the same as for `test.each`.
563563+564564+```ts
565565+// `each` spreads arrays
566566+test.each([
567567+ [1, 1, 2],
568568+ [1, 2, 3],
569569+ [2, 1, 3],
570570+])('add(%i, %i) -> %i', (a, b, expected) => { // [!code --]
571571+ expect(a + b).toBe(expected)
572572+})
573573+574574+// `for` doesn't spread arrays (notice the square brackets around the arguments)
575575+test.for([
576576+ [1, 1, 2],
577577+ [1, 2, 3],
578578+ [2, 1, 3],
579579+])('add(%i, %i) -> %i', ([a, b, expected]) => { // [!code ++]
580580+ expect(a + b).toBe(expected)
581581+})
582582+```
583583+584584+The 2nd argument is [`TestContext`](/guide/test-context) and can be used for concurrent snapshots, for example:
585585+586586+```ts
587587+test.concurrent.for([
588588+ [1, 1],
589589+ [1, 2],
590590+ [2, 1],
591591+])('add(%i, %i)', ([a, b], { expect }) => {
592592+ expect(a + b).toMatchSnapshot()
593593+})
594594+```
595595+596596+## test.describe <Version>4.1.0</Version> {#test-describe}
597597+598598+Scoped `describe`. See [describe](/api/describe) for more information.
599599+600600+## test.beforeEach
601601+602602+Scoped `beforeEach` hook that inherits types from [`test.extend`](#test-extend). See [beforeEach](/api/hooks#beforeeach) for more information.
603603+604604+## test.afterEach
605605+606606+Scoped `afterEach` hook that inherits types from [`test.extend`](#test-extend). See [afterEach](/api/hooks#aftereach) for more information.
607607+608608+## test.beforeAll
609609+610610+Scoped `beforeAll` hook. See [beforeAll](/api/hooks#beforeall) for more information.
611611+612612+## test.afterAll
613613+614614+Scoped `afterAll` hook. See [afterAll](/api/hooks#afterall) for more information.
615615+616616+## test.aroundEach <Version>4.1.0</Version> {#test-aroundeach}
617617+618618+Scoped `aroundEach` hook that inherits types from [`test.extend`](#test-extend). See [aroundEach](/api/hooks#aroundeach) for more information.
619619+620620+## test.aroundAll <Version>4.1.0</Version> {#test-aroundall}
621621+622622+Scoped `aroundAll` hook. See [aroundAll](/api/hooks#aroundall) for more information.
623623+624624+## bench <Experimental /> {#bench}
625625+626626+- **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`
627627+628628+::: danger
629629+Benchmarking is experimental and does not follow SemVer.
630630+:::
631631+632632+`bench` defines a benchmark. In Vitest terms, benchmark is a function that defines a series of operations. Vitest runs this function multiple times to display different performance results.
633633+634634+Vitest uses the [`tinybench`](https://github.com/tinylibs/tinybench) library under the hood, inheriting all its options that can be used as a third argument.
635635+636636+```ts
637637+import { bench } from 'vitest'
638638+639639+bench('normal sorting', () => {
640640+ const x = [1, 5, 4, 2, 3]
641641+ x.sort((a, b) => {
642642+ return a - b
643643+ })
644644+}, { time: 1000 })
645645+```
646646+647647+```ts
648648+export interface Options {
649649+ /**
650650+ * time needed for running a benchmark task (milliseconds)
651651+ * @default 500
652652+ */
653653+ time?: number
654654+655655+ /**
656656+ * number of times that a task should run if even the time option is finished
657657+ * @default 10
658658+ */
659659+ iterations?: number
660660+661661+ /**
662662+ * function to get the current timestamp in milliseconds
663663+ */
664664+ now?: () => number
665665+666666+ /**
667667+ * An AbortSignal for aborting the benchmark
668668+ */
669669+ signal?: AbortSignal
670670+671671+ /**
672672+ * Throw if a task fails (events will not work if true)
673673+ */
674674+ throws?: boolean
675675+676676+ /**
677677+ * warmup time (milliseconds)
678678+ * @default 100ms
679679+ */
680680+ warmupTime?: number
681681+682682+ /**
683683+ * warmup iterations
684684+ * @default 5
685685+ */
686686+ warmupIterations?: number
687687+688688+ /**
689689+ * setup function to run before each benchmark task (cycle)
690690+ */
691691+ setup?: Hook
692692+693693+ /**
694694+ * teardown function to run after each benchmark task (cycle)
695695+ */
696696+ teardown?: Hook
697697+}
698698+```
699699+After the test case is run, the output structure information is as follows:
700700+701701+```
702702+ name hz min max mean p75 p99 p995 p999 rme samples
703703+· normal sorting 6,526,368.12 0.0001 0.3638 0.0002 0.0002 0.0002 0.0002 0.0004 ±1.41% 652638
704704+```
705705+```ts
706706+export interface TaskResult {
707707+ /*
708708+ * the last error that was thrown while running the task
709709+ */
710710+ error?: unknown
711711+712712+ /**
713713+ * The amount of time in milliseconds to run the benchmark task (cycle).
714714+ */
715715+ totalTime: number
716716+717717+ /**
718718+ * the minimum value in the samples
719719+ */
720720+ min: number
721721+ /**
722722+ * the maximum value in the samples
723723+ */
724724+ max: number
725725+726726+ /**
727727+ * the number of operations per second
728728+ */
729729+ hz: number
730730+731731+ /**
732732+ * how long each operation takes (ms)
733733+ */
734734+ period: number
735735+736736+ /**
737737+ * task samples of each task iteration time (ms)
738738+ */
739739+ samples: number[]
740740+741741+ /**
742742+ * samples mean/average (estimate of the population mean)
743743+ */
744744+ mean: number
745745+746746+ /**
747747+ * samples variance (estimate of the population variance)
748748+ */
749749+ variance: number
750750+751751+ /**
752752+ * samples standard deviation (estimate of the population standard deviation)
753753+ */
754754+ sd: number
755755+756756+ /**
757757+ * standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean)
758758+ */
759759+ sem: number
760760+761761+ /**
762762+ * degrees of freedom
763763+ */
764764+ df: number
765765+766766+ /**
767767+ * critical value of the samples
768768+ */
769769+ critical: number
770770+771771+ /**
772772+ * margin of error
773773+ */
774774+ moe: number
775775+776776+ /**
777777+ * relative margin of error
778778+ */
779779+ rme: number
780780+781781+ /**
782782+ * median absolute deviation
783783+ */
784784+ mad: number
785785+786786+ /**
787787+ * p50/median percentile
788788+ */
789789+ p50: number
790790+791791+ /**
792792+ * p75 percentile
793793+ */
794794+ p75: number
795795+796796+ /**
797797+ * p99 percentile
798798+ */
799799+ p99: number
800800+801801+ /**
802802+ * p995 percentile
803803+ */
804804+ p995: number
805805+806806+ /**
807807+ * p999 percentile
808808+ */
809809+ p999: number
810810+}
811811+```
812812+813813+### bench.skip
814814+815815+- **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`
816816+817817+You can use `bench.skip` syntax to skip running certain benchmarks.
818818+819819+```ts
820820+import { bench } from 'vitest'
821821+822822+bench.skip('normal sorting', () => {
823823+ const x = [1, 5, 4, 2, 3]
824824+ x.sort((a, b) => {
825825+ return a - b
826826+ })
827827+})
828828+```
829829+830830+### bench.only
831831+832832+- **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`
833833+834834+Use `bench.only` to only run certain benchmarks in a given suite. This is useful when debugging.
835835+836836+```ts
837837+import { bench } from 'vitest'
838838+839839+bench.only('normal sorting', () => {
840840+ const x = [1, 5, 4, 2, 3]
841841+ x.sort((a, b) => {
842842+ return a - b
843843+ })
844844+})
845845+```
846846+847847+### bench.todo
848848+849849+- **Type:** `(name: string | Function) => void`
850850+851851+Use `bench.todo` to stub benchmarks to be implemented later.
852852+853853+```ts
854854+import { bench } from 'vitest'
855855+856856+bench.todo('unimplemented test')
857857+```
+1-1
docs/api/vi.md
···628628:::
629629630630::: tip
631631-You can call [`vi.restoreAllMocks`](#vi-restoreallmocks) inside [`afterEach`](/api/#aftereach) (or enable [`test.restoreMocks`](/config/#restoreMocks)) to restore all methods to their original implementations after every test. This will restore the original [object descriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), so you won't be able to change method's implementation anymore, unless you spy again:
631631+You can call [`vi.restoreAllMocks`](#vi-restoreallmocks) inside [`afterEach`](/api/hooks#aftereach) (or enable [`test.restoreMocks`](/config/#restoreMocks)) to restore all methods to their original implementations after every test. This will restore the original [object descriptor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty), so you won't be able to change method's implementation anymore, unless you spy again:
632632633633```ts
634634const cart = {
+3-3
docs/config/allowonly.md
···99- **Default**: `!process.env.CI`
1010- **CLI:** `--allowOnly`, `--allowOnly=false`
11111212-By default, Vitest does not permit tests marked with the [`only`](/api/#test-only) flag in Continuous Integration (CI) environments. Conversely, in local development environments, Vitest allows these tests to run.
1212+By default, Vitest does not permit tests marked with the [`only`](/api/test#test-only) flag in Continuous Integration (CI) environments. Conversely, in local development environments, Vitest allows these tests to run.
13131414::: info
1515Vitest uses [`std-env`](https://www.npmjs.com/package/std-env) package to detect the environment.
···3232```
3333:::
34343535-When enabled, Vitest will not fail the test suite if tests marked with [`only`](/api/#test-only) are detected, including in CI environments.
3535+When enabled, Vitest will not fail the test suite if tests marked with [`only`](/api/test#test-only) are detected, including in CI environments.
36363737-When disabled, Vitest will fail the test suite if tests marked with [`only`](/api/#test-only) are detected, including in local development environments.
3737+When disabled, Vitest will fail the test suite if tests marked with [`only`](/api/test#test-only) are detected, including in local development environments.
+2-2
docs/config/browser.md
···472472473473- `testName: string`
474474475475- The [`test`](/api/#test)'s name, including parent
476476- [`describe`](/api/#describe), sanitized.
475475+ The [`test`](/api/test)'s name, including parent
476476+ [`describe`](/api/describe), sanitized.
477477478478- `attachmentsDir: string`
479479
+1-1
docs/config/fileparallelism.md
···1212Should all test files run in parallel. Setting this to `false` will override `maxWorkers` option to `1`.
13131414::: tip
1515-This option doesn't affect tests running in the same file. If you want to run those in parallel, use `concurrent` option on [describe](/api/#describe-concurrent) or via [a config](#sequence-concurrent).
1515+This option doesn't affect tests running in the same file. If you want to run those in parallel, use `concurrent` option on [describe](/api/describe#describe-concurrent) or via [a config](#sequence-concurrent).
1616:::
+1-1
docs/config/sequence.md
···148148- `parallel` will run hooks in a single group in parallel (hooks in parent suites will still run before the current suite's hooks)
149149150150::: tip
151151-This option doesn't affect [`onTestFinished`](/api/#ontestfinished). It is always called in reverse order.
151151+This option doesn't affect [`onTestFinished`](/api/hooks#ontestfinished). It is always called in reverse order.
152152:::
153153154154## sequence.setupFiles {#sequence-setupfiles}
+5-53
docs/config/tags.md
···9999100100## Test Options
101101102102-Tags can define test options that will be applied to every test marked with the tag. These options are merged with the test's own options, with the test's options taking precedence.
102102+Tags can define [test options](/api/test#test-options) that will be applied to every test marked with the tag. These options are merged with the test's own options, with the test's options taking precedence.
103103104104-### timeout
104104+::: warning
105105+The [`retry.condition`](/api/test#retry) can onle be a regexp because the config values need to be serialised.
105106106106-- **Type:** `number`
107107-108108-Test timeout in milliseconds.
109109-110110-### retry
111111-112112-- **Type:** `number | { count?: number, delay?: number, condition?: RegExp }`
113113-114114-Retry configuration for the test. If a number, specifies how many times to retry. If an object, allows fine-grained retry control.
115115-116116-### repeats
117117-118118-- **Type:** `number`
119119-120120-How many times the test will run again.
121121-122122-### concurrent
123123-124124-- **Type:** `boolean`
125125-126126-Whether suites and tests run concurrently.
127127-128128-### sequential
129129-130130-- **Type:** `boolean`
131131-132132-Whether tests run sequentially.
133133-134134-### skip
135135-136136-- **Type:** `boolean`
137137-138138-Whether the test should be skipped.
139139-140140-### only
141141-142142-- **Type:** `boolean`
143143-144144-Should this test be the only one running in a suite.
145145-146146-### todo
147147-148148-- **Type:** `boolean`
149149-150150-Whether the test should be skipped and marked as a todo.
151151-152152-### fails
153153-154154-- **Type:** `boolean`
155155-156156-Whether the test is expected to fail. If it does, the test will pass, otherwise it will fail.
107107+Tags also cannot apply other [tags](/api/test#tags) via these options.
108108+:::
157109158110## Example
159111
+14
docs/guide/cli-generated.md
···844844- **Config:** [experimental.printImportBreakdown](/config/experimental#experimental-printimportbreakdown)
845845846846Print import breakdown after the summary. If the reporter doesn't support summary, this will have no effect. Note that UI's "Module Graph" tab always has an import breakdown.
847847+848848+### experimental.viteModuleRunner
849849+850850+- **CLI:** `--experimental.viteModuleRunner`
851851+- **Config:** [experimental.viteModuleRunner](/config/experimental#experimental-vitemodulerunner)
852852+853853+Control whether Vitest uses Vite's module runner to run the code or fallback to the native `import`. (default: `true`)
854854+855855+### experimental.nodeLoader
856856+857857+- **CLI:** `--experimental.nodeLoader`
858858+- **Config:** [experimental.nodeLoader](/config/experimental#experimental-nodeloader)
859859+860860+Controls whether Vitest will use Node.js Loader API to process in-source or mocked files. This has no effect if `viteModuleRunner` is enabled. Disabling this can increase performance. (default: `true`)
+2-2
docs/guide/features.md
···7777})
7878```
79798080-You can also use `.skip`, `.only`, and `.todo` with concurrent suites and tests. Read more in the [API Reference](/api/#test-concurrent).
8080+You can also use `.skip`, `.only`, and `.todo` with concurrent suites and tests. Read more in the [API Reference](/api/test#test-concurrent).
81818282::: warning
8383When running concurrent tests, Snapshots and Assertions must use `expect` from the local [Test Context](/guide/test-context) to ensure the right test is detected.
···192192193193## Benchmarking <Badge type="warning">Experimental</Badge> {#benchmarking}
194194195195-You can run benchmark tests with [`bench`](/api/#bench) function via [Tinybench](https://github.com/tinylibs/tinybench) to compare performance results.
195195+You can run benchmark tests with [`bench`](/api/test#bench) function via [Tinybench](https://github.com/tinylibs/tinybench) to compare performance results.
196196197197```ts [sort.bench.ts]
198198import { bench, describe } from 'vitest'
+1-1
docs/guide/index.md
···9292If you are using Bun as your package manager, make sure to use `bun run test` command instead of `bun test`, otherwise Bun will run its own test runner.
9393:::
94949595-Learn more about the usage of Vitest, see the [API](/api/) section.
9595+Learn more about the usage of Vitest, see the [API](/api/test) section.
96969797## Configuring Vitest
9898
+3-3
docs/guide/lifecycle.md
···131131 - `beforeEach` hooks execute (in order defined, or based on [`sequence.hooks`](/config/sequence#sequence-hooks))
132132 - Test function executes
133133 - `afterEach` hooks execute (reverse order by default with `sequence.hooks: 'stack'`)
134134- - [`onTestFinished`](/api/#ontestfinished) callbacks run (always in reverse order)
135135- - If test failed: [`onTestFailed`](/api/#ontestfailed) callbacks run
134134+ - [`onTestFinished`](/api/hooks#ontestfinished) callbacks run (always in reverse order)
135135+ - If test failed: [`onTestFailed`](/api/hooks#ontestfailed) callbacks run
136136 - Note: if `repeats` or `retry` are set, all of these steps are executed again
1371375. **`afterAll` hooks** - Run once after all tests in the suite complete
138138···317317- [Isolation Configuration](/config/isolate)
318318- [Pool Configuration](/config/pool)
319319- [Extending Reporters](/guide/advanced/reporters) - for reporter lifecycle events
320320-- [Test API Reference](/api/) - for hook APIs and test functions
320320+- [Test API Reference](/api/hooks) - for hook APIs
+3-3
docs/guide/migration.md
···319319320320- `maxThreads` and `maxForks` are now `maxWorkers`.
321321- Environment variables `VITEST_MAX_THREADS` and `VITEST_MAX_FORKS` are now `VITEST_MAX_WORKERS`.
322322-- `singleThread` and `singleFork` are now `maxWorkers: 1, isolate: false`. If your tests were relying on module reset between tests, you'll need to add [setupFile](/config/setupfiles) that calls [`vi.resetModules()`](/api/vi.html#vi-resetmodules) in [`beforeAll` test hook](/api/#beforeall).
322322+- `singleThread` and `singleFork` are now `maxWorkers: 1, isolate: false`. If your tests were relying on module reset between tests, you'll need to add [setupFile](/config/setupfiles) that calls [`vi.resetModules()`](/api/vi.html#vi-resetmodules) in [`beforeAll` test hook](/api/hooks#beforeall).
323323- `poolOptions` is removed. All previous `poolOptions` are now top-level options. The `memoryLimit` of VM pools is renamed to `vmMemoryLimit`.
324324- `threads.useAtomics` is removed. If you have a use case for this, feel free to open a new feature request.
325325- Custom pool interface has been rewritten, see [Custom Pool](/guide/advanced/pool#custom-pool)
···573573574574### Replace property
575575576576-If you want to modify the object, you will use [replaceProperty API](https://jestjs.io/docs/jest-object#jestreplacepropertyobject-propertykey-value) in Jest, you can use [`vi.stubEnv`](/api/#vi-stubenv) or [`vi.spyOn`](/api/vi#vi-spyon) to do the same also in Vitest.
576576+If you want to modify the object, you will use [replaceProperty API](https://jestjs.io/docs/jest-object#jestreplacepropertyobject-propertykey-value) in Jest, you can use [`vi.stubEnv`](/api/vi#vi-stubenv) or [`vi.spyOn`](/api/vi#vi-spyon) to do the same also in Vitest.
577577578578### Done Callback
579579···583583584584### Hooks
585585586586-`beforeAll`/`beforeEach` hooks may return [teardown function](/api/#setup-and-teardown) in Vitest. Because of that you may need to rewrite your hooks declarations, if they return something other than `undefined` or `null`:
586586+`beforeAll`/`beforeEach` hooks may return [teardown function](/api/hooks#beforeach) in Vitest. Because of that you may need to rewrite your hooks declarations, if they return something other than `undefined` or `null`:
587587588588```ts
589589beforeEach(() => setActivePinia(createTestingPinia())) // [!code --]
+1-1
docs/guide/parallelism.md
···20202121Unlike _test files_, Vitest runs _tests_ in sequence. This means that tests inside a single test file will run in the order they are defined.
22222323-Vitest supports the [`concurrent`](/api/#test-concurrent) option to run tests together. If this option is set, Vitest will group concurrent tests in the same _file_ (the number of simultaneously running tests depends on the [`maxConcurrency`](/config/#maxconcurrency) option) and run them with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all).
2323+Vitest supports the [`concurrent`](/api/test#test-concurrent) option to run tests together. If this option is set, Vitest will group concurrent tests in the same _file_ (the number of simultaneously running tests depends on the [`maxConcurrency`](/config/#maxconcurrency) option) and run them with [`Promise.all`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all).
24242525Vitest doesn't perform any smart analysis and doesn't create additional workers to run these tests. This means that the performance of your tests will improve only if you rely heavily on asynchronous operations. For example, these tests will still run one after another even though the `concurrent` option is specified. This is because they are synchronous:
2626
+2-2
docs/guide/test-context.md
···119119120120#### `onTestFailed`
121121122122-The [`onTestFailed`](/api/#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
122122+The [`onTestFailed`](/api/hooks#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
123123124124#### `onTestFinished`
125125126126-The [`onTestFinished`](/api/#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
126126+The [`onTestFinished`](/api/hooks#ontestfailed) hook bound to the current test. This API is useful if you are running tests concurrently and need to have a special handling only for this specific test.
127127128128## Extend Test Context
129129
+2
packages/vitest/globals.d.ts
···1414 let afterAll: typeof import('vitest')['afterAll']
1515 let beforeEach: typeof import('vitest')['beforeEach']
1616 let afterEach: typeof import('vitest')['afterEach']
1717+ let aroundEach: typeof import('vitest')['aroundEach']
1818+ let aroundAll: typeof import('vitest')['aroundAll']
1719 let onTestFailed: typeof import('vitest')['onTestFailed']
1820 let onTestFinished: typeof import('vitest')['onTestFinished']
1921}
···110110111111- `testName: string`
112112113113- The [`test`](/api/#test)'s name, including parent
114114- [`describe`](/api/#describe), sanitized.
113113+ The [`test`](/api/test)'s name, including parent
114114+ [`describe`](/api/describe), sanitized.
115115116116- `attachmentsDir: string`
117117
+1-1
docs/guide/browser/trace-view.md
···2525```
2626:::
27272828-By default, Vitest will generate a trace file for each test. You can also configure it to only generate traces on test failures by setting `trace` to `'on-first-retry'`, `'on-all-retries'` or `'retain-on-failure'`. The files will be saved in `__traces__` folder next to your test files. The name of the trace includes the project name, the test name, the [`repeats` count and `retry` count](/api/#test-api-reference):
2828+By default, Vitest will generate a trace file for each test. You can also configure it to only generate traces on test failures by setting `trace` to `'on-first-retry'`, `'on-all-retries'` or `'retain-on-failure'`. The files will be saved in `__traces__` folder next to your test files. The name of the trace includes the project name, the test name, the [`repeats`](/api/test#repeats) count and [`retry`](/api/test#retry) count:
29293030```
3131chromium-my-test-0-0.trace.zip
+12
packages/runner/src/errors.ts
···1919 this.reason = reason
2020 }
2121}
2222+2323+export class AroundHookSetupError extends Error {
2424+ public name = 'AroundHookSetupError'
2525+}
2626+2727+export class AroundHookTeardownError extends Error {
2828+ public name = 'AroundHookTeardownError'
2929+}
3030+3131+export class AroundHookMultipleCallsError extends Error {
3232+ public name = 'AroundHookMultipleCallsError'
3333+}
+28
packages/runner/src/fixture.ts
···132132 cleanupFnArrayMap.delete(context)
133133}
134134135135+/**
136136+ * Returns the current number of cleanup functions registered for the context.
137137+ * This can be used as a checkpoint to later clean up only fixtures added after this point.
138138+ */
139139+export function getFixtureCleanupCount(context: object): number {
140140+ return cleanupFnArrayMap.get(context)?.length ?? 0
141141+}
142142+143143+/**
144144+ * Cleans up only fixtures that were added after the given checkpoint index.
145145+ * This is used by aroundEach to clean up fixtures created inside runTest()
146146+ * while preserving fixtures that were created for aroundEach itself.
147147+ */
148148+export async function callFixtureCleanupFrom(context: object, fromIndex: number): Promise<void> {
149149+ const cleanupFnArray = cleanupFnArrayMap.get(context)
150150+ if (!cleanupFnArray || cleanupFnArray.length <= fromIndex) {
151151+ return
152152+ }
153153+ // Get items added after the checkpoint
154154+ const toCleanup = cleanupFnArray.slice(fromIndex)
155155+ // Clean up in reverse order
156156+ for (const cleanup of toCleanup.reverse()) {
157157+ await cleanup()
158158+ }
159159+ // Remove cleaned up items from the array, keeping items before checkpoint
160160+ cleanupFnArray.length = fromIndex
161161+}
162162+135163export function withFixtures(runner: VitestRunner, fn: Function, testContext?: TestContext) {
136164 return (hookContext?: TestContext): any => {
137165 const context: (TestContext & { [key: string]: any }) | undefined
+143
packages/runner/src/hooks.ts
···11+import type { VitestRunner } from './types'
12import type {
23 AfterAllListener,
34 AfterEachListener,
55+ AroundAllListener,
66+ AroundEachListener,
47 BeforeAllListener,
58 BeforeEachListener,
69 OnTestFailedHandler,
···21242225const CLEANUP_TIMEOUT_KEY = Symbol.for('VITEST_CLEANUP_TIMEOUT')
2326const CLEANUP_STACK_TRACE_KEY = Symbol.for('VITEST_CLEANUP_STACK_TRACE')
2727+const AROUND_TIMEOUT_KEY = Symbol.for('VITEST_AROUND_TIMEOUT')
2828+const AROUND_STACK_TRACE_KEY = Symbol.for('VITEST_AROUND_STACK_TRACE')
24292530export function getBeforeHookCleanupCallback(hook: Function, result: any, context?: TestContext): Function | undefined {
2631 if (typeof result === 'function') {
···265270 )
266271 },
267272)
273273+274274+/**
275275+ * Registers a callback function that wraps around all tests within the current suite.
276276+ * The callback receives a `runSuite` function that must be called to run the suite's tests.
277277+ * This hook is useful for scenarios where you need to wrap an entire suite in a context
278278+ * (e.g., starting a server, opening a database connection that all tests share).
279279+ *
280280+ * **Note:** When multiple `aroundAll` hooks are registered, they are nested inside each other.
281281+ * The first registered hook is the outermost wrapper.
282282+ *
283283+ * **Note:** Unlike `aroundEach`, the `aroundAll` hook does not receive test context or support fixtures,
284284+ * as it runs at the suite level before any individual test context is created.
285285+ *
286286+ * @param {Function} fn - The callback function that wraps the suite. Must call `runSuite()` to run the tests.
287287+ * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
288288+ * @returns {void}
289289+ * @example
290290+ * ```ts
291291+ * // Example of using aroundAll to wrap suite in a tracing span
292292+ * aroundAll(async (runSuite) => {
293293+ * await tracer.trace('test-suite', runSuite);
294294+ * });
295295+ * ```
296296+ * @example
297297+ * ```ts
298298+ * // Example of using aroundAll with AsyncLocalStorage context
299299+ * aroundAll(async (runSuite) => {
300300+ * await asyncLocalStorage.run({ suiteId: 'my-suite' }, runSuite);
301301+ * });
302302+ * ```
303303+ */
304304+export function aroundAll(
305305+ fn: AroundAllListener,
306306+ timeout?: number,
307307+): void {
308308+ assertTypes(fn, '"aroundAll" callback', ['function'])
309309+ const stackTraceError = new Error('STACK_TRACE_ERROR')
310310+ const resolvedTimeout = timeout ?? getDefaultHookTimeout()
311311+312312+ return getCurrentSuite().on(
313313+ 'aroundAll',
314314+ Object.assign(fn, {
315315+ [AROUND_TIMEOUT_KEY]: resolvedTimeout,
316316+ [AROUND_STACK_TRACE_KEY]: stackTraceError,
317317+ }),
318318+ )
319319+}
320320+321321+/**
322322+ * Registers a callback function that wraps around each test within the current suite.
323323+ * The callback receives a `runTest` function that must be called to run the test.
324324+ * This hook is useful for scenarios where you need to wrap tests in a context (e.g., database transactions).
325325+ *
326326+ * **Note:** When multiple `aroundEach` hooks are registered, they are nested inside each other.
327327+ * The first registered hook is the outermost wrapper.
328328+ *
329329+ * @param {Function} fn - The callback function that wraps the test. Must call `runTest()` to run the test.
330330+ * @param {number} [timeout] - Optional timeout in milliseconds for the hook. If not provided, the default hook timeout from the runner's configuration is used.
331331+ * @returns {void}
332332+ * @example
333333+ * ```ts
334334+ * // Example of using aroundEach to wrap tests in a database transaction
335335+ * aroundEach(async (runTest) => {
336336+ * await database.transaction(() => runTest());
337337+ * });
338338+ * ```
339339+ * @example
340340+ * ```ts
341341+ * // Example of using aroundEach with fixtures
342342+ * aroundEach(async (runTest, { db }) => {
343343+ * await db.transaction(() => runTest());
344344+ * });
345345+ * ```
346346+ */
347347+export function aroundEach<ExtraContext = object>(
348348+ fn: AroundEachListener<ExtraContext>,
349349+ timeout?: number,
350350+): void {
351351+ assertTypes(fn, '"aroundEach" callback', ['function'])
352352+ const stackTraceError = new Error('STACK_TRACE_ERROR')
353353+ const resolvedTimeout = timeout ?? getDefaultHookTimeout()
354354+ const runner = getRunner()
355355+356356+ // Create a wrapper function that supports fixtures in the second argument (context)
357357+ // withFixtures resolves fixtures into context, then we call fn with all 3 args
358358+ const wrappedFn: AroundEachListener<ExtraContext> = withAroundEachFixtures(runner, fn)
359359+360360+ // Store timeout and stack trace on the function for use in callAroundEachHooks
361361+ // Setup and teardown phases will each have their own timeout
362362+ return getCurrentSuite<ExtraContext>().on(
363363+ 'aroundEach',
364364+ Object.assign(wrappedFn, {
365365+ [AROUND_TIMEOUT_KEY]: resolvedTimeout,
366366+ [AROUND_STACK_TRACE_KEY]: stackTraceError,
367367+ }),
368368+ )
369369+}
370370+371371+/**
372372+ * Wraps an aroundEach listener to support fixtures.
373373+ * Similar to withFixtures, but handles the aroundEach signature where:
374374+ * - First arg is runTest function
375375+ * - Second arg is context (where fixtures are destructured from)
376376+ * - Third arg is suite
377377+ */
378378+function withAroundEachFixtures<ExtraContext>(
379379+ runner: VitestRunner,
380380+ fn: AroundEachListener<ExtraContext>,
381381+): AroundEachListener<ExtraContext> {
382382+ // Create the wrapper that will be returned
383383+ const wrapper: AroundEachListener<ExtraContext> = (runTest, context, suite) => {
384384+ // Create inner function that will be passed to withFixtures
385385+ // This function receives context (with fixtures resolved) and calls original fn
386386+ const innerFn = (ctx: any) => fn(runTest, ctx, suite)
387387+ // Set fixture index to 1 to tell parser to look at second arg of original fn
388388+ // Set toString to return original fn string so parser extracts correct params
389389+ ;(innerFn as any).__VITEST_FIXTURE_INDEX__ = 1
390390+ ;(innerFn as any).toString = () => fn.toString()
391391+392392+ // Use withFixtures to resolve fixtures, passing context as the hook context
393393+ const fixtureResolver = withFixtures(runner, innerFn)
394394+ return fixtureResolver(context)
395395+ }
396396+397397+ return wrapper
398398+}
399399+400400+export function getAroundHookTimeout(hook: Function): number {
401401+ return AROUND_TIMEOUT_KEY in hook && typeof hook[AROUND_TIMEOUT_KEY] === 'number'
402402+ ? hook[AROUND_TIMEOUT_KEY]
403403+ : getDefaultHookTimeout()
404404+}
405405+406406+export function getAroundHookStackTrace(hook: Function): Error | undefined {
407407+ return AROUND_STACK_TRACE_KEY in hook && hook[AROUND_STACK_TRACE_KEY] instanceof Error
408408+ ? hook[AROUND_STACK_TRACE_KEY]
409409+ : undefined
410410+}
268411269412function createTestHook<T>(
270413 name: string,