

Vitest
======

A Vite-native unit test framework. It's fast!



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/>

Node API
========



**WARNING**Vitest exposes experimental private API. Breaking changes might not follow semver, please pin Vitest's version when using it.



startVitest
-----------


You can start running Vitest tests using its Node API:



js
```
import { startVitest } from 'vitest/node'

const vitest = await startVitest('test')

await vitest?.close()
```


```
import { startVitest } from 'vitest/node'

const vitest = await startVitest('test')

await vitest?.close()
```


`startVitest` function returns `Vitest` instance if tests can be started. It returns `undefined`, if one of the following occurs:


* Vitest didn't find "vite" package (usually installed with Vitest)
* If coverage is enabled and run mode is "test", but the coverage package is not installed (`@vitest/coverage-v8` or `@vitest/coverage-istanbul`)
* If the environment package is not installed (`jsdom`/`happy-dom`/`@edge-runtime/vm`)


If `undefined` is returned or tests failed during the run, Vitest sets `process.exitCode` to `1`.


If watch mode is not enabled, Vitest will call `close` method.


If watch mode is enabled and the terminal supports TTY, Vitest will register console shortcuts.


You can pass down a list of filters as a second argument. Vitest will run only tests that contain at least one of the passed-down strings in their file path.


Additionally, you can use the third argument to pass in CLI arguments, which will override any test config options.


Alternatively, you can pass in the complete Vite config as the fourth argument, which will take precedence over any other user-defined options.


createVitest
------------


You can create Vitest instance yourself using `createVitest` function. It returns the same `Vitest` instance as `startVitest`, but it doesn't start tests and doesn't validate installed packages.



js
```
import { createVitest } from 'vitest/node'

const vitest = await createVitest('test', {
  watch: false,
})
```


```
import { createVitest } from 'vitest/node'

const vitest = await createVitest('test', {
  watch: false,
})
```


Vitest
------


Vitest instance requires the current test mode. It can be either:


* `test` when running runtime tests
* `benchmark` when running benchmarks
* `typecheck` when running type tests


### mode


#### test


Test mode will only call functions inside `test` or `it`, and throws an error when `bench` is encountered. This mode uses `include` and `exclude` options in the config to find test files.


#### benchmark


Benchmark mode calls `bench` functions and throws an error, when it encounters `test` or `it`. This mode uses `benchmark.include` and `benchmark.exclude` options in the config to find benchmark files.


#### typecheck


Typecheck mode doesn't *run* tests. It only analyses types and gives a summary. This mode uses `typecheck.include` and `typecheck.exclude` options in the config to find files to analyze.


### start


You can start running tests or benchmarks with `start` method. You can pass an array of strings to filter test files.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/advanced/api.html>

Why Vitest
==========



**NOTE**This guide assumes that you are familiar with Vite. A good way to start learning more is to read the [Why Vite Guide](https://vitejs.dev/guide/why.html), and [Next generation frontend tooling with ViteJS](https://www.youtube.com/watch?v=UJypSr8IhKY), a stream where [Evan You](https://twitter.com/youyuxi) did a demo explaining the main concepts.



The need for a Vite native test runner
--------------------------------------


Vite's out-of-the-box support for common web patterns, features like glob imports and SSR primitives, and its many plugins and integrations are fostering a vibrant ecosystem. Its dev and build story are key to its success. For docs, there are several SSG-based alternatives powered by Vite. Vite's Unit Testing story hasn't been clear though. Existing options like [Jest](https://jestjs.io/) were created in a different context. There is a lot of duplication between Jest and Vite, forcing users to configure two different pipelines.


Using Vite dev server to transform your files during testing, enables the creation of a simple runner that doesn't need to deal with the complexity of transforming source files and can solely focus on providing the best DX during testing. A test runner that uses the same configuration of your App (through `vite.config.js`), sharing a common transformation pipeline during dev, build, and test time. That is extensible with the same plugin API that lets you and the maintainers of your tools provide first-class integration with Vite. A tool that is built with Vite in mind from the start, taking advantage of its improvements in DX, like its instant Hot Module Reload (HMR). This is Vitest, a blazing fast unit-test framework powered by Vite.


Given Jest's massive adoption, Vitest provides a compatible API that allows you to use it as a drop-in replacement in most projects. It also includes the most common features required when setting up your unit tests (mocking, snapshots, coverage). Vitest cares a lot about performance and uses Worker threads to run as much as possible in parallel. Some ports have seen test running an order of magnitude faster. Watch mode is enabled by default, aligning itself with the way Vite pushes for a dev first experience. Even with all these improvements in DX, Vitest stays lightweight by carefully choosing its dependencies (or directly inlining needed pieces).


**Vitest aims to position itself as the Test Runner of choice for Vite projects, and as a solid alternative even for projects not using Vite.**


Continue reading in the [Getting Started Guide](index)


How is Vitest Different from X?
-------------------------------


You can check out the [Comparisons](comparisons) section for more details on how Vitest differs from other similar tools.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/why.html>

Test API Reference
==================


The following types are used in the type signatures below



ts
```
type Awaitable<T> = T | PromiseLike<T>
type TestFunction = () => Awaitable<void>

interface TestOptions {
  /**
   * Will fail the test if it takes too long to execute
   */
  timeout?: number
  /**
   * Will retry the test specific number of times if it fails
   *
   * @default 0
   */
  retry?: number
  /**
   * Will repeat the same test several times even if it fails each time
   * If you have "retry" option and it fails, it will use every retry in each cycle
   * Useful for debugging random failings
   *
   * @default 0
   */
  repeats?: number
}
```


```
type Awaitable<T> = T | PromiseLike<T>
type TestFunction = () => Awaitable<void>

interface TestOptions {
  /**
   * Will fail the test if it takes too long to execute
   */
  timeout?: number
  /**
   * Will retry the test specific number of times if it fails
   *
   * @default 0
   */
  retry?: number
  /**
   * Will repeat the same test several times even if it fails each time
   * If you have "retry" option and it fails, it will use every retry in each cycle
   * Useful for debugging random failings
   *
   * @default 0
   */
  repeats?: number
}
```


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.



**TIP**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).



test
----


* **Type:** `(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => void`
* **Alias:** `it`


`test` defines a set of related expectations. It receives the test name and a function that holds the expectations to test.


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/index#testtimeout)



ts
```
import { expect, test } from 'vitest'

test('should work as expected', () => {
  expect(Math.sqrt(4)).toBe(2)
})
```


```
import { expect, test } from 'vitest'

test('should work as expected', () => {
  expect(Math.sqrt(4)).toBe(2)
})
```


### test.extend


* **Type:** `<T extends Record<string, any>>(fixtures: Fixtures<T>): TestAPI<ExtraContext & T>`
* **Alias:** `it.extend`
* **Version:** Vitest 0.32.3


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#test-extend) for more information.



ts
```
import { expect, test } from 'vitest'

const todos = []
const archive = []

const myTest = test.extend({
  todos: async ({ task }, use) => {
    todos.push(1, 2, 3)
    await use(todos)
    todos.length = 0
  },
  archive
})

myTest('add item', ({ todos }) => {
  expect(todos.length).toBe(3)

  todos.push(4)
  expect(todos.length).toBe(4)
})
```


```
import { expect, test } from 'vitest'

const todos = []
const archive = []

const myTest = test.extend({
  todos: async ({ task }, use) => {
    todos.push(1, 2, 3)
    await use(todos)
    todos.length = 0
  },
  archive
})

myTest('add item', ({ todos }) => {
  expect(todos.length).toBe(3)

  todos.push(4)
  expect(todos.length).toBe(4)
})
```


### test.skip


* **Type:** `(name: string | Function, fn: TestFunction, timeout?: number | TestOptions) => void`
* **Alias:** `it.skip`


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.



ts
```
import { assert, test } from 'vitest'

test.skip('skipped test', () => {
  // Test skipped, no error
  assert.equal(Math.sqrt(4), 3)
})
```


```
import { assert, test } from 'vitest'

test.skip('skipped test', () => {
  // Test skipped, no error
  assert.equal(Math.sqrt(4), 3)
})
```


### test.skipIf


* **Type:** `(condition: any) => Test`
* **Alias:** `it.skipIf`


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.



ts
```
import { assert, test } from 'vitest'

const isDev = process.env.NODE_ENV === 'development'

test.skipIf(isDev)('prod only test', () => {
  // this test only runs in production
})
```


```
import { assert, test } from 'vitest'

const isDev = process.env.NODE_ENV === 'development'

test.skipIf(isDev)('prod only test', () => {
  // this test only runs in production
})
```



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



### test.runIf


* **Type:** `(condition: any) => Test`
* **Alias:** `it.runIf`


Opposite of [test.skipIf](#test-skipif).



ts
```
import { assert, test } from 'vitest'

const isDev = process.env.NODE_ENV === 'development'

test.runIf(isDev)('dev only test', () => {
  // this test only runs in development
})
```


```
import { assert, test } from 'vitest'

const isDev = process.env.NODE_ENV === 'development'

test.runIf(isDev)('dev only test', () => {
  // this test only runs in development
})
```



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



### test.only


* **Type:** `(name: string | Function, fn: TestFunction, timeout?: number) => void`
* **Alias:** `it.only`


Use `test.only` to only run certain tests in a given suite. This is useful when debugging.


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/index#testtimeout).



ts
```
import { assert, test } from 'vitest'

test.only('test', () => {
  // Only this test (and others marked with only) are run
  assert.equal(Math.sqrt(4), 2)
})
```


```
import { assert, test } from 'vitest'

test.only('test', () => {
  // Only this test (and others marked with only) are run
  assert.equal(Math.sqrt(4), 2)
})
```


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.


In order to do that run `vitest` with specific file containing the tests in question.




```
# vitest interesting.test.ts
```


```
# vitest interesting.test.ts
```


### test.concurrent


* **Type:** `(name: string | Function, fn: TestFunction, timeout?: number) => void`
* **Alias:** `it.concurrent`


`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).



ts
```
import { describe, test } from 'vitest'

// The two tests marked with concurrent will be run in parallel
describe('suite', () => {
  test('serial test', async () => { /* ... */ })
  test.concurrent('concurrent test 1', async () => { /* ... */ })
  test.concurrent('concurrent test 2', async () => { /* ... */ })
})
```


```
import { describe, test } from 'vitest'

// The two tests marked with concurrent will be run in parallel
describe('suite', () => {
  test('serial test', async () => { /* ... */ })
  test.concurrent('concurrent test 1', async () => { /* ... */ })
  test.concurrent('concurrent test 2', async () => { /* ... */ })
})
```


`test.skip`, `test.only`, and `test.todo` works with concurrent tests. All the following combinations are valid:



ts
```
test.concurrent(/* ... */)
test.skip.concurrent(/* ... */) // or test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */) // or test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */) // or test.concurrent.todo(/* ... */)
```


```
test.concurrent(/* ... */)
test.skip.concurrent(/* ... */) // or test.concurrent.skip(/* ... */)
test.only.concurrent(/* ... */) // or test.concurrent.only(/* ... */)
test.todo.concurrent(/* ... */) // or test.concurrent.todo(/* ... */)
```


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.



ts
```
test.concurrent('test 1', async ({ expect }) => {
  expect(foo).toMatchSnapshot()
})
test.concurrent('test 2', async ({ expect }) => {
  expect(foo).toMatchSnapshot()
})
```


```
test.concurrent('test 1', async ({ expect }) => {
  expect(foo).toMatchSnapshot()
})
test.concurrent('test 2', async ({ expect }) => {
  expect(foo).toMatchSnapshot()
})
```



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



### test.todo


* **Type:** `(name: string | Function) => void`
* **Alias:** `it.todo`


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.



ts
```
// An entry will be shown in the report for this test
test.todo('unimplemented test')
```


```
// An entry will be shown in the report for this test
test.todo('unimplemented test')
```


### test.fails


* **Type:** `(name: string | Function, fn: TestFunction, timeout?: number) => void`
* **Alias:** `it.fails`


Use `test.fails` to indicate that an assertion will fail explicitly.



ts
```
import { expect, test } from 'vitest'

function myAsyncFunc() {
  return new Promise(resolve => resolve(1))
}
test.fails('fail test', async () => {
  await expect(myAsyncFunc()).rejects.toBe(1)
})
```


```
import { expect, test } from 'vitest'

function myAsyncFunc() {
  return new Promise(resolve => resolve(1))
}
test.fails('fail test', async () => {
  await expect(myAsyncFunc()).rejects.toBe(1)
})
```



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



### test.each


* **Type:** `(cases: ReadonlyArray<T>, ...args: any[]) => void`
* **Alias:** `it.each`


Use `test.each` when you need to run the same test with different variables. 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.


	+ `%s`: string
	+ `%d`: number
	+ `%i`: integer
	+ `%f`: floating point value
	+ `%j`: json
	+ `%o`: object
	+ `%#`: index of the test case
	+ `%%`: single percent sign ('%')
ts
```
test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
  expect(a + b).toBe(expected)
})

// this will return
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3
```


```
test.each([
  [1, 1, 2],
  [1, 2, 3],
  [2, 1, 3],
])('add(%i, %i) -> %i', (a, b, expected) => {
  expect(a + b).toBe(expected)
})

// this will return
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3
```


You can also access object properties with `$` prefix, if you are using objects as arguments:



ts
```
test.each([
  { a: 1, b: 1, expected: 2 },
  { a: 1, b: 2, expected: 3 },
  { a: 2, b: 1, expected: 3 },
])('add($a, $b) -> $expected', ({ a, b, expected }) => {
  expect(a + b).toBe(expected)
})

// this will return
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3
```


```
test.each([
  { a: 1, b: 1, expected: 2 },
  { a: 1, b: 2, expected: 3 },
  { a: 2, b: 1, expected: 3 },
])('add($a, $b) -> $expected', ({ a, b, expected }) => {
  expect(a + b).toBe(expected)
})

// this will return
// ✓ add(1, 1) -> 2
// ✓ add(1, 2) -> 3
// ✓ add(2, 1) -> 3
```


You can also access Object attributes with `.`, if you are using objects as arguments:



ts
```
test.each`
a               | b      | expected
${{ val: 1 }}   | ${'b'} | ${'1b'}
${{ val: 2 }}   | ${'b'} | ${'2b'}
${{ val: 3 }}   | ${'b'} | ${'3b'}
`('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
  expect(a.val + b).toBe(expected)
})

// this will return
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3b
```


```
test.each`
a               | b      | expected
${{ val: 1 }}   | ${'b'} | ${'1b'}
${{ val: 2 }}   | ${'b'} | ${'2b'}
${{ val: 3 }}   | ${'b'} | ${'3b'}
`('add($a.val, $b) -> $expected', ({ a, b, expected }) => {
  expect(a.val + b).toBe(expected)
})

// this will return
// ✓ add(1, b) -> 1b
// ✓ add(2, b) -> 2b
// ✓ add(3, b) -> 3b
```


Starting from Vitest 0.25.3, you can also use template string table.


	+ First row should be column names, separated by `|`;
	+ One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
ts
```
test.each`
  a               | b      | expected
  ${1}            | ${1}   | ${2}
  ${'a'}          | ${'b'} | ${'ab'}
  ${[]}           | ${'b'} | ${'b'}
  ${{}}           | ${'b'} | ${'[object Object]b'}
  ${{ asd: 1 }}   | ${'b'} | ${'[object Object]b'}
`('returns $expected when $a is added $b', ({ a, b, expected }) => {
  expect(a + b).toBe(expected)
})
```


```
test.each`
  a               | b      | expected
  ${1}            | ${1}   | ${2}
  ${'a'}          | ${'b'} | ${'ab'}
  ${[]}           | ${'b'} | ${'b'}
  ${{}}           | ${'b'} | ${'[object Object]b'}
  ${{ asd: 1 }}   | ${'b'} | ${'[object Object]b'}
`('returns $expected when $a is added $b', ({ a, b, expected }) => {
  expect(a + b).toBe(expected)
})
```


If you want to have access to `TestContext`, use `describe.each` with a single test.



**TIP**Vitest processes `$values` with chai `format` method. If the value is too truncated, you can increase [chaiConfig.truncateThreshold](../config/index#chaiconfig-truncatethreshold) in your config file.




**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



bench
-----


* **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`


`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.


Vitest uses [`tinybench`](https://github.com/tinylibs/tinybench) library under the hood, inheriting all its options that can be used as a third argument.



ts
```
import { bench } from 'vitest'

bench('normal sorting', () => {
  const x = [1, 5, 4, 2, 3]
  x.sort((a, b) => {
    return a - b
  })
}, { time: 1000 })
```


```
import { bench } from 'vitest'

bench('normal sorting', () => {
  const x = [1, 5, 4, 2, 3]
  x.sort((a, b) => {
    return a - b
  })
}, { time: 1000 })
```



ts
```
export interface Options {
  /**
   * time needed for running a benchmark task (milliseconds)
   * @default 500
   */
  time?: number

  /**
   * number of times that a task should run if even the time option is finished
   * @default 10
   */
  iterations?: number

  /**
   * function to get the current timestamp in milliseconds
   */
  now?: () => number

  /**
   * An AbortSignal for aborting the benchmark
   */
  signal?: AbortSignal

  /**
   * warmup time (milliseconds)
   * @default 100ms
   */
  warmupTime?: number

  /**
   * warmup iterations
   * @default 5
   */
  warmupIterations?: number

  /**
   * setup function to run before each benchmark task (cycle)
   */
  setup?: Hook

  /**
   * teardown function to run after each benchmark task (cycle)
   */
  teardown?: Hook
}
```


```
export interface Options {
  /**
   * time needed for running a benchmark task (milliseconds)
   * @default 500
   */
  time?: number

  /**
   * number of times that a task should run if even the time option is finished
   * @default 10
   */
  iterations?: number

  /**
   * function to get the current timestamp in milliseconds
   */
  now?: () => number

  /**
   * An AbortSignal for aborting the benchmark
   */
  signal?: AbortSignal

  /**
   * warmup time (milliseconds)
   * @default 100ms
   */
  warmupTime?: number

  /**
   * warmup iterations
   * @default 5
   */
  warmupIterations?: number

  /**
   * setup function to run before each benchmark task (cycle)
   */
  setup?: Hook

  /**
   * teardown function to run after each benchmark task (cycle)
   */
  teardown?: Hook
}
```


### bench.skip


* **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`


You can use `bench.skip` syntax to skip running certain benchmarks.



ts
```
import { bench } from 'vitest'

bench.skip('normal sorting', () => {
  const x = [1, 5, 4, 2, 3]
  x.sort((a, b) => {
    return a - b
  })
})
```


```
import { bench } from 'vitest'

bench.skip('normal sorting', () => {
  const x = [1, 5, 4, 2, 3]
  x.sort((a, b) => {
    return a - b
  })
})
```


### bench.only


* **Type:** `(name: string | Function, fn: BenchFunction, options?: BenchOptions) => void`


Use `bench.only` to only run certain benchmarks in a given suite. This is useful when debugging.



ts
```
import { bench } from 'vitest'

bench.only('normal sorting', () => {
  const x = [1, 5, 4, 2, 3]
  x.sort((a, b) => {
    return a - b
  })
})
```


```
import { bench } from 'vitest'

bench.only('normal sorting', () => {
  const x = [1, 5, 4, 2, 3]
  x.sort((a, b) => {
    return a - b
  })
})
```


### bench.todo


* **Type:** `(name: string | Function) => void`


Use `bench.todo` to stub benchmarks to be implemented later.



ts
```
import { bench } from 'vitest'

bench.todo('unimplemented test')
```


```
import { bench } from 'vitest'

bench.todo('unimplemented test')
```


describe
--------


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.



ts
```
// basic.spec.ts
// organizing tests

import { describe, expect, test } from 'vitest'

const person = {
  isActive: true,
  age: 32,
}

describe('person', () => {
  test('person is defined', () => {
    expect(person).toBeDefined()
  })

  test('is active', () => {
    expect(person.isActive).toBeTruthy()
  })

  test('age limit', () => {
    expect(person.age).toBeLessThanOrEqual(32)
  })
})
```


```
// basic.spec.ts
// organizing tests

import { describe, expect, test } from 'vitest'

const person = {
  isActive: true,
  age: 32,
}

describe('person', () => {
  test('person is defined', () => {
    expect(person).toBeDefined()
  })

  test('is active', () => {
    expect(person.isActive).toBeTruthy()
  })

  test('age limit', () => {
    expect(person.age).toBeLessThanOrEqual(32)
  })
})
```



ts
```
// basic.bench.ts
// organizing benchmarks

import { bench, describe } from 'vitest'

describe('sort', () => {
  bench('normal', () => {
    const x = [1, 5, 4, 2, 3]
    x.sort((a, b) => {
      return a - b
    })
  })

  bench('reverse', () => {
    const x = [1, 5, 4, 2, 3]
    x.reverse().sort((a, b) => {
      return a - b
    })
  })
})
```


```
// basic.bench.ts
// organizing benchmarks

import { bench, describe } from 'vitest'

describe('sort', () => {
  bench('normal', () => {
    const x = [1, 5, 4, 2, 3]
    x.sort((a, b) => {
      return a - b
    })
  })

  bench('reverse', () => {
    const x = [1, 5, 4, 2, 3]
    x.reverse().sort((a, b) => {
      return a - b
    })
  })
})
```


You can also nest describe blocks if you have a hierarchy of tests or benchmarks:



ts
```
import { describe, expect, test } from 'vitest'

function numberToCurrency(value) {
  if (typeof value !== 'number')
    throw new Error('Value must be a number')

  return value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

describe('numberToCurrency', () => {
  describe('given an invalid number', () => {
    test('composed of non-numbers to throw error', () => {
      expect(() => numberToCurrency('abc')).toThrowError()
    })
  })

  describe('given a valid number', () => {
    test('returns the correct currency format', () => {
      expect(numberToCurrency(10000)).toBe('10,000.00')
    })
  })
})
```


```
import { describe, expect, test } from 'vitest'

function numberToCurrency(value) {
  if (typeof value !== 'number')
    throw new Error('Value must be a number')

  return value.toFixed(2).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

describe('numberToCurrency', () => {
  describe('given an invalid number', () => {
    test('composed of non-numbers to throw error', () => {
      expect(() => numberToCurrency('abc')).toThrowError()
    })
  })

  describe('given a valid number', () => {
    test('returns the correct currency format', () => {
      expect(numberToCurrency(10000)).toBe('10,000.00')
    })
  })
})
```


### describe.skip


* **Type:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void`


Use `describe.skip` in a suite to avoid running a particular describe block.



ts
```
import { assert, describe, test } from 'vitest'

describe.skip('skipped suite', () => {
  test('sqrt', () => {
    // Suite skipped, no error
    assert.equal(Math.sqrt(4), 3)
  })
})
```


```
import { assert, describe, test } from 'vitest'

describe.skip('skipped suite', () => {
  test('sqrt', () => {
    // Suite skipped, no error
    assert.equal(Math.sqrt(4), 3)
  })
})
```


### describe.skipIf


* **Type:** `(condition: any) => void`


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.



ts
```
import { assert, test } from 'vitest'

const isDev = process.env.NODE_ENV === 'development'

describe.skipIf(isDev)('prod only test', () => {
  // this test only runs in production
})
```


```
import { assert, test } from 'vitest'

const isDev = process.env.NODE_ENV === 'development'

describe.skipIf(isDev)('prod only test', () => {
  // this test only runs in production
})
```



**WARNING**You cannot use this syntax when using Vitest as [type checker](../guide/testing-types).



### describe.only


* **Type:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void`


Use `describe.only` to only run certain suites



ts
```
// Only this suite (and others marked with only) are run
describe.only('suite', () => {
  test('sqrt', () => {
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('other suite', () => {
  // ... will be skipped
})
```


```
// Only this suite (and others marked with only) are run
describe.only('suite', () => {
  test('sqrt', () => {
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('other suite', () => {
  // ... will be skipped
})
```


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.


In order to do that run `vitest` with specific file containing the tests in question.




```
# vitest interesting.test.ts
```


```
# vitest interesting.test.ts
```


### describe.concurrent


* **Type:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void`


`describe.concurrent` in a suite marks every tests as concurrent



ts
```
// All tests within this suite will be run in parallel
describe.concurrent('suite', () => {
  test('concurrent test 1', async () => { /* ... */ })
  test('concurrent test 2', async () => { /* ... */ })
  test.concurrent('concurrent test 3', async () => { /* ... */ })
})
```


```
// All tests within this suite will be run in parallel
describe.concurrent('suite', () => {
  test('concurrent test 1', async () => { /* ... */ })
  test('concurrent test 2', async () => { /* ... */ })
  test.concurrent('concurrent test 3', async () => { /* ... */ })
})
```


`.skip`, `.only`, and `.todo` works with concurrent suites. All the following combinations are valid:



ts
```
describe.concurrent(/* ... */)
describe.skip.concurrent(/* ... */) // or describe.concurrent.skip(/* ... */)
describe.only.concurrent(/* ... */) // or describe.concurrent.only(/* ... */)
describe.todo.concurrent(/* ... */) // or describe.concurrent.todo(/* ... */)
```


```
describe.concurrent(/* ... */)
describe.skip.concurrent(/* ... */) // or describe.concurrent.skip(/* ... */)
describe.only.concurrent(/* ... */) // or describe.concurrent.only(/* ... */)
describe.todo.concurrent(/* ... */) // or describe.concurrent.todo(/* ... */)
```


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.



ts
```
describe.concurrent('suite', () => {
  test('concurrent test 1', async ({ expect }) => {
    expect(foo).toMatchSnapshot()
  })
  test('concurrent test 2', async ({ expect }) => {
    expect(foo).toMatchSnapshot()
  })
})
```


```
describe.concurrent('suite', () => {
  test('concurrent test 1', async ({ expect }) => {
    expect(foo).toMatchSnapshot()
  })
  test('concurrent test 2', async ({ expect }) => {
    expect(foo).toMatchSnapshot()
  })
})
```



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



### describe.shuffle


* **Type:** `(name: string | Function, fn: TestFunction, options?: number | TestOptions) => void`


Vitest provides a way to run all tests in random order via CLI flag [`--sequence.shuffle`](../guide/cli) or config option [`sequence.shuffle`](../config/index#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.



ts
```
describe.shuffle('suite', () => {
  test('random test 1', async () => { /* ... */ })
  test('random test 2', async () => { /* ... */ })
  test('random test 3', async () => { /* ... */ })
})
// order depends on sequence.seed option in config (Date.now() by default)
```


```
describe.shuffle('suite', () => {
  test('random test 1', async () => { /* ... */ })
  test('random test 2', async () => { /* ... */ })
  test('random test 3', async () => { /* ... */ })
})
// order depends on sequence.seed option in config (Date.now() by default)
```


`.skip`, `.only`, and `.todo` works with random suites.



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



### describe.todo


* **Type:** `(name: string | Function) => void`


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.



ts
```
// An entry will be shown in the report for this suite
describe.todo('unimplemented suite')
```


```
// An entry will be shown in the report for this suite
describe.todo('unimplemented suite')
```


### describe.each


* **Type:** `(cases: ReadonlyArray<T>, ...args: any[]): (name: string | Function, fn: (...args: T[]) => void, options?: number | TestOptions) => void`


Use `describe.each` if you have more than one test that depends on the same data.



ts
```
describe.each([
  { a: 1, b: 1, expected: 2 },
  { a: 1, b: 2, expected: 3 },
  { a: 2, b: 1, expected: 3 },
])('describe object add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected)
  })

  test(`returned value not be greater than ${expected}`, () => {
    expect(a + b).not.toBeGreaterThan(expected)
  })

  test(`returned value not be less than ${expected}`, () => {
    expect(a + b).not.toBeLessThan(expected)
  })
})
```


```
describe.each([
  { a: 1, b: 1, expected: 2 },
  { a: 1, b: 2, expected: 3 },
  { a: 2, b: 1, expected: 3 },
])('describe object add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected)
  })

  test(`returned value not be greater than ${expected}`, () => {
    expect(a + b).not.toBeGreaterThan(expected)
  })

  test(`returned value not be less than ${expected}`, () => {
    expect(a + b).not.toBeLessThan(expected)
  })
})
```


Starting from Vitest 0.25.3, you can also use template string table.


	+ First row should be column names, separated by `|`;
	+ One or more subsequent rows of data supplied as template literal expressions using `${value}` syntax.
ts
```
describe.each`
  a               | b      | expected
  ${1}            | ${1}   | ${2}
  ${'a'}          | ${'b'} | ${'ab'}
  ${[]}           | ${'b'} | ${'b'}
  ${{}}           | ${'b'} | ${'[object Object]b'}
  ${{ asd: 1 }}   | ${'b'} | ${'[object Object]b'}
`('describe template string add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected)
  })
})
```


```
describe.each`
  a               | b      | expected
  ${1}            | ${1}   | ${2}
  ${'a'}          | ${'b'} | ${'ab'}
  ${[]}           | ${'b'} | ${'b'}
  ${{}}           | ${'b'} | ${'[object Object]b'}
  ${{ asd: 1 }}   | ${'b'} | ${'[object Object]b'}
`('describe template string add($a, $b)', ({ a, b, expected }) => {
  test(`returns ${expected}`, () => {
    expect(a + b).toBe(expected)
  })
})
```



**WARNING**You cannot use this syntax, when using Vitest as [type checker](../guide/testing-types).



Setup and Teardown
------------------


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.


### beforeEach


* **Type:** `beforeEach(fn: () => Awaitable<void>, timeout?: number)`


Register a callback to be called before each of the tests in the current context runs. If the function returns a promise, Vitest waits until the promise resolve before running the test.


Optionally, you can pass a timeout (in milliseconds) defining how long to wait before terminating. The default is 5 seconds.



ts
```
import { beforeEach } from 'vitest'

beforeEach(async () => {
  // Clear mocks and add some testing data after before each test run
  await stopMocking()
  await addUser({ name: 'John' })
})
```


```
import { beforeEach } from 'vitest'

beforeEach(async () => {
  // Clear mocks and add some testing data after before each test run
  await stopMocking()
  await addUser({ name: 'John' })
})
```


Here, the `beforeEach` ensures that user is added for each test.


Since Vitest v0.10.0, `beforeEach` also accepts an optional cleanup function (equivalent to `afterEach`).



ts
```
import { beforeEach } from 'vitest'

beforeEach(async () => {
  // called once before each test run
  await prepareSomething()

  // clean up function, called once after each test run
  return async () => {
    await resetSomething()
  }
})
```


```
import { beforeEach } from 'vitest'

beforeEach(async () => {
  // called once before each test run
  await prepareSomething()

  // clean up function, called once after each test run
  return async () => {
    await resetSomething()
  }
})
```


### afterEach


* **Type:** `afterEach(fn: () => Awaitable<void>, timeout?: number)`


Register a callback to be called after each one of the tests in the current context completes. If the function returns a promise, Vitest waits until the promise resolve before continuing.


Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds.



ts
```
import { afterEach } from 'vitest'

afterEach(async () => {
  await clearTestingData() // clear testing data after each test run
})
```


```
import { afterEach } from 'vitest'

afterEach(async () => {
  await clearTestingData() // clear testing data after each test run
})
```


Here, the `afterEach` ensures that testing data is cleared after each test runs.


### beforeAll


* **Type:** `beforeAll(fn: () => Awaitable<void>, timeout?: number)`


Register a callback to be called once before starting to run all tests in the current context. If the function returns a promise, Vitest waits until the promise resolve before running tests.


Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds.



ts
```
import { beforeAll } from 'vitest'

beforeAll(async () => {
  await startMocking() // called once before all tests run
})
```


```
import { beforeAll } from 'vitest'

beforeAll(async () => {
  await startMocking() // called once before all tests run
})
```


Here the `beforeAll` ensures that the mock data is set up before tests run.


Since Vitest v0.10.0, `beforeAll` also accepts an optional cleanup function (equivalent to `afterAll`).



ts
```
import { beforeAll } from 'vitest'

beforeAll(async () => {
  // called once before all tests run
  await startMocking()

  // clean up function, called once after all tests run
  return async () => {
    await stopMocking()
  }
})
```


```
import { beforeAll } from 'vitest'

beforeAll(async () => {
  // called once before all tests run
  await startMocking()

  // clean up function, called once after all tests run
  return async () => {
    await stopMocking()
  }
})
```


### afterAll


* **Type:** `afterAll(fn: () => Awaitable<void>, timeout?: number)`


Register a callback to be called once after all tests have run in the current context. If the function returns a promise, Vitest waits until the promise resolve before continuing.


Optionally, you can provide a timeout (in milliseconds) for specifying how long to wait before terminating. The default is 5 seconds.



ts
```
import { afterAll } from 'vitest'

afterAll(async () => {
  await stopMocking() // this method is called after all tests run
})
```


```
import { afterAll } from 'vitest'

afterAll(async () => {
  await stopMocking() // this method is called after all tests run
})
```


Here the `afterAll` ensures that `stopMocking` method is called after all tests run.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/api/>

Features
========


* [Vite](https://vitejs.dev)'s config, transformers, resolvers, and plugins.
* Use the same setup from your app to run the tests!
* [Smart & instant watch mode, like HMR for tests!](https://twitter.com/antfu7/status/1468233216939245579)
* Component testing for Vue, React, Svelte, Lit and more
* Out-of-the-box TypeScript / JSX support
* ESM first, top level await
* Workers multi-threading via [Tinypool](https://github.com/tinylibs/tinypool)
* Benchmarking support with [Tinybench](https://github.com/tinylibs/tinybench)
* Filtering, timeouts, concurrent for suite and tests
* [Workspace](workspace) support
* [Jest-compatible Snapshot](snapshot)
* [Chai](https://www.chaijs.com/) built-in for assertions + [Jest expect](https://jestjs.io/docs/expect) compatible APIs
* [Tinyspy](https://github.com/tinylibs/tinyspy) built-in for mocking
* [happy-dom](https://github.com/capricorn86/happy-dom) or [jsdom](https://github.com/jsdom/jsdom) for DOM mocking
* Code coverage via [v8](https://v8.dev/blog/javascript-code-coverage) or [istanbul](https://istanbul.js.org/)
* Rust-like [in-source testing](in-source)
* Type Testing via [expect-type](https://github.com/mmkal/expect-type)


[Learn how to write your first test by Video](https://vueschool.io/lessons/your-first-test?friend=vueuse)Shared config between test, dev and build
-----------------------------------------


Vite's config, transformers, resolvers, and plugins. Use the same setup from your app to run the tests.


Learn more at [Configuring Vitest](index#configuring-vitest).


Watch Mode
----------



bash
```
$ vitest
```


```
$ vitest
```


When you modify your source code or the test files, Vitest smartly searches the module graph and only reruns the related tests, [just like how HMR works in Vite!](https://twitter.com/antfu7/status/1468233216939245579)


`vitest` starts in `watch mode` **by default in development environment** and `run mode` in CI environment (when `process.env.CI` presents) smartly. You can use `vitest watch` or `vitest run` to explicitly specify the desired mode.


Common web idioms out-of-the-box
--------------------------------


Out-of-the-box ES Module / TypeScript / JSX support / PostCSS


Threads
-------


Workers multi-threading via [Tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina)), allowing tests to run simultaneously. Threads are enabled by default in Vitest, and can be disabled by passing `--no-threads` in the CLI.


Vitest also isolates each file's environment so env mutations in one file don't affect others. Isolation can be disabled by passing `--no-isolate` to the CLI (trading correctness for run performance).


Test Filtering
--------------


Vitest provided many ways to narrow down the tests to run in order to speed up testing so you can focus on development.


Learn more about [Test Filtering](filtering).


Running tests concurrently
--------------------------


Use `.concurrent` in consecutive tests to run them in parallel.



ts
```
import { describe, it } from 'vitest'

// The two tests marked with concurrent will be run in parallel
describe('suite', () => {
  it('serial test', async () => { /* ... */ })
  it.concurrent('concurrent test 1', async ({ expect }) => { /* ... */ })
  it.concurrent('concurrent test 2', async ({ expect }) => { /* ... */ })
})
```


```
import { describe, it } from 'vitest'

// The two tests marked with concurrent will be run in parallel
describe('suite', () => {
  it('serial test', async () => { /* ... */ })
  it.concurrent('concurrent test 1', async ({ expect }) => { /* ... */ })
  it.concurrent('concurrent test 2', async ({ expect }) => { /* ... */ })
})
```


If you use `.concurrent` on a suite, every test in it will be run in parallel.



ts
```
import { describe, it } from 'vitest'

// All tests within this suite will be run in parallel
describe.concurrent('suite', () => {
  it('concurrent test 1', async ({ expect }) => { /* ... */ })
  it('concurrent test 2', async ({ expect }) => { /* ... */ })
  it.concurrent('concurrent test 3', async ({ expect }) => { /* ... */ })
})
```


```
import { describe, it } from 'vitest'

// All tests within this suite will be run in parallel
describe.concurrent('suite', () => {
  it('concurrent test 1', async ({ expect }) => { /* ... */ })
  it('concurrent test 2', async ({ expect }) => { /* ... */ })
  it.concurrent('concurrent test 3', async ({ expect }) => { /* ... */ })
})
```


You can also use `.skip`, `.only`, and `.todo` with concurrent suites and tests. Read more in the [API Reference](../api/index#test-concurrent).



**WARNING**When running concurrent tests, Snapshots and Assertions must use `expect` from the local [Test Context](test-context) to ensure the right test is detected.



Snapshot
--------


[Jest-compatible](https://jestjs.io/docs/snapshot-testing) snapshot support.



ts
```
import { expect, it } from 'vitest'

it('renders correctly', () => {
  const result = render()
  expect(result).toMatchSnapshot()
})
```


```
import { expect, it } from 'vitest'

it('renders correctly', () => {
  const result = render()
  expect(result).toMatchSnapshot()
})
```


Learn more at [Snapshot](snapshot).


Chai and Jest `expect` compatibility
------------------------------------


[Chai](https://www.chaijs.com/) is built-in for assertions plus [Jest `expect`](https://jestjs.io/docs/expect)-compatible APIs.


Notice that if you are using third-party libraries that add matchers, setting `test.globals` to `true` will provide better compatibility.


Mocking
-------


[Tinyspy](https://github.com/tinylibs/tinyspy) is built-in for mocking with `jest`-compatible APIs on `vi` object.



ts
```
import { expect, vi } from 'vitest'

const fn = vi.fn()

fn('hello', 1)

expect(vi.isMockFunction(fn)).toBe(true)
expect(fn.mock.calls[0]).toEqual(['hello', 1])

fn.mockImplementation(arg => arg)

fn('world', 2)

expect(fn.mock.results[1].value).toBe('world')
```


```
import { expect, vi } from 'vitest'

const fn = vi.fn()

fn('hello', 1)

expect(vi.isMockFunction(fn)).toBe(true)
expect(fn.mock.calls[0]).toEqual(['hello', 1])

fn.mockImplementation(arg => arg)

fn('world', 2)

expect(fn.mock.results[1].value).toBe('world')
```


Vitest supports both [happy-dom](https://github.com/capricorn86/happy-dom) or [jsdom](https://github.com/jsdom/jsdom) for mocking DOM and browser APIs. They don't come with Vitest, you might need to install them:



bash
```
$ npm i -D happy-dom
# or
$ npm i -D jsdom
```


```
$ npm i -D happy-dom
# or
$ npm i -D jsdom
```


After that, change the `environment` option in your config file:



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environment: 'happy-dom', // or 'jsdom', 'node'
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environment: 'happy-dom', // or 'jsdom', 'node'
  },
})
```


Learn more at [Mocking](mocking).


Coverage
--------


Vitest supports Native code coverage via [`v8`](https://v8.dev/blog/javascript-code-coverage) and instrumented code coverage via [`istanbul`](https://istanbul.js.org/).



json
```
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}
```


```
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}
```


Learn more at [Coverage](coverage).


In-source testing
-----------------


Vitest also provides a way to run tests within your source code along with the implementation, similar to [Rust's module tests](https://doc.rust-lang.org/book/ch11-03-test-organization.html#the-tests-module-and-cfgtest).


This makes the tests share the same closure as the implementations and able to test against private states without exporting. Meanwhile, it also brings the feedback loop closer for development.



ts
```
// src/index.ts

// the implementation
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}
```


```
// src/index.ts

// the implementation
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}
```


Learn more at [In-source testing](in-source).


Benchmarking `experimental`
---------------------------


Since Vitest 0.23.0, you can run benchmark tests with [`bench`](../api/index#bench) function via [Tinybench](https://github.com/tinylibs/tinybench) to compare performance results.



ts
```
import { bench, describe } from 'vitest'

describe('sort', () => {
  bench('normal', () => {
    const x = [1, 5, 4, 2, 3]
    x.sort((a, b) => {
      return a - b
    })
  })

  bench('reverse', () => {
    const x = [1, 5, 4, 2, 3]
    x.reverse().sort((a, b) => {
      return a - b
    })
  })
})
```


```
import { bench, describe } from 'vitest'

describe('sort', () => {
  bench('normal', () => {
    const x = [1, 5, 4, 2, 3]
    x.sort((a, b) => {
      return a - b
    })
  })

  bench('reverse', () => {
    const x = [1, 5, 4, 2, 3]
    x.reverse().sort((a, b) => {
      return a - b
    })
  })
})
```


Type Testing `experimental`
---------------------------


Since Vitest 0.25.0 you can [write tests](testing-types) to catch type regressions. Vitest comes with [`expect-type`](https://github.com/mmkal/expect-type) package to provide you with a similar and easy to understand API.



ts
```
import { assertType, expectTypeOf } from 'vitest'
import { mount } from './mount.js'

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction()
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>()

  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }))
})
```


```
import { assertType, expectTypeOf } from 'vitest'
import { mount } from './mount.js'

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction()
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>()

  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }))
})
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/features.html>

Getting Started
===============


Overview
--------


Vitest is a blazing fast unit test framework powered by Vite.


You can learn more about the rationale behind the project in the [Why Vitest](why) section.


Trying Vitest Online
--------------------


You can try Vitest online on [StackBlitz](https://vitest.new). It runs Vitest directly in the browser, and it is almost identical to the local setup but doesn't require installing anything on your machine.


Adding Vitest to your Project
-----------------------------


[Learn how to install by Video](https://vueschool.io/lessons/how-to-install-vitest?friend=vueuse)

npmyarnpnpm



bash
```
npm install -D vitest
```


```
npm install -D vitest
```



bash
```
yarn add -D vitest
```


```
yarn add -D vitest
```



bash
```
pnpm add -D vitest
```


```
pnpm add -D vitest
```





**TIP**Vitest requires Vite >=v3.0.0 and Node >=v14.18



It is recommended that you install a copy of `vitest` in your `package.json`, using one of the methods listed above. However, if you would prefer to run `vitest` directly, you can use `npx vitest` (the `npx` command comes with npm and Node.js).


The `npx` command will execute the command either from a local `node_modules/.bin` installing any packages needed in order for the command to run. By default, npx will check whether command exists in $PATH, or in the local project binaries, and execute that. If command is not found, it will be installed prior to execution.


Configuring Vitest
------------------


One of the main advantages of Vitest is its unified configuration with Vite. If present, `vitest` will read your root `vite.config.ts` to match with the plugins and setup as your Vite app. For example, your Vite [resolve.alias](https://vitejs.dev/config/shared-options.html#resolve-alias) and [plugins](https://vitejs.dev/guide/using-plugins.html) configuration will work out-of-the-box. If you want a different configuration during testing, you can:


* Create `vitest.config.ts`, which will have the higher priority
* Pass `--config` option to CLI, e.g. `vitest --config ./path/to/vitest.config.ts`
* Use `process.env.VITEST` or `mode` property on `defineConfig` (will be set to `test` if not overridden) to conditionally apply different configuration in `vite.config.ts`


To configure `vitest` itself, add `test` property in your Vite config. You'll also need to add a reference to Vitest types using a [triple slash command](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) at the top of your config file, if you are importing `defineConfig` from `vite` itself.



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    // ...
  },
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    // ...
  },
})
```


See the list of config options in the [Config Reference](../config/index)


Workspaces Support
------------------


Run different project configurations inside the same project with [Vitest Workspaces](workspace). You can define a list of files and folders that define your workspace in `vitest.workspace` file. The file supports `js`/`ts`/`json` extensions. This feature works great with monorepo setups.



ts
```
import { defineWorkspace } from 'vitest/config'

export default defineWorkspace([
  // you can use a list of glob patterns to define your workspaces
  // Vitest expects a list of config files
  // or directories where there is a config file
  'packages/*',
  'tests/*/vitest.config.{e2e,unit}.ts',
  // you can even run the same tests,
  // but with different configs in the same "vitest" process
  {
    test: {
      name: 'happy-dom',
      root: './shared_tests',
      environment: 'happy-dom',
      setupFiles: ['./setup.happy-dom.ts'],
    },
  },
  {
    test: {
      name: 'node',
      root: './shared_tests',
      environment: 'node',
      setupFiles: ['./setup.node.ts'],
    },
  },
])
```


```
import { defineWorkspace } from 'vitest/config'

export default defineWorkspace([
  // you can use a list of glob patterns to define your workspaces
  // Vitest expects a list of config files
  // or directories where there is a config file
  'packages/*',
  'tests/*/vitest.config.{e2e,unit}.ts',
  // you can even run the same tests,
  // but with different configs in the same "vitest" process
  {
    test: {
      name: 'happy-dom',
      root: './shared_tests',
      environment: 'happy-dom',
      setupFiles: ['./setup.happy-dom.ts'],
    },
  },
  {
    test: {
      name: 'node',
      root: './shared_tests',
      environment: 'node',
      setupFiles: ['./setup.node.ts'],
    },
  },
])
```


Command Line Interface
----------------------


In a project where Vitest is installed, you can use the `vitest` binary in your npm scripts, or run it directly with `npx vitest`. Here are the default npm scripts in a scaffolded Vitest project:



json
```
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}
```


```
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}
```


To run tests once without watching for file changes, use `vitest run`. You can specify additional CLI options like `--port` or `--https`. For a full list of CLI options, run `npx vitest --help` in your project.


Learn more about the [Command Line Interface](cli)


IDE Integrations
----------------


We also provided a official extension for Visual Studio Code to enhance your testing experience with Vitest.


[Install from VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=ZixuanChen.vitest-explorer)


Learn more about [IDE Integrations](ide)


Examples
--------




| Example | Source | Playground |
| --- | --- | --- |
| `basic` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/basic) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/basic?initialPath=__vitest__/) |
| `fastify` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/fastify) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/fastify?initialPath=__vitest__/) |
| `graphql` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/graphql) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/graphql?initialPath=__vitest__/) |
| `image-snapshot` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/image-snapshot) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/image-snapshot?initialPath=__vitest__/) |
| `lit` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/lit) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/lit?initialPath=__vitest__/) |
| `mocks` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/mocks) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/mocks?initialPath=__vitest__/) |
| `nextjs` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/nextjs) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/nextjs?initialPath=__vitest__/) |
| `playwright` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/playwright) |  |
| `puppeteer` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/puppeteer) |  |
| `react-enzyme` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/react-enzyme) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/react-enzyme?initialPath=__vitest__/) |
| `react-mui` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/react-mui) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/react-mui?initialPath=__vitest__/) |
| `react-storybook` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/react-storybook) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/react-storybook?initialPath=__vitest__/) |
| `react-testing-lib-msw` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/react-testing-lib-msw) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/react-testing-lib-msw?initialPath=__vitest__/) |
| `react-testing-lib` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/react-testing-lib) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/react-testing-lib?initialPath=__vitest__/) |
| `react` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/react) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/react?initialPath=__vitest__/) |
| `ruby` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/ruby) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/ruby?initialPath=__vitest__/) |
| `solid` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/solid) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/solid?initialPath=__vitest__/) |
| `svelte` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/svelte) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/svelte?initialPath=__vitest__/) |
| `vitesse` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/vitesse) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/vitesse?initialPath=__vitest__/) |
| `vue-jsx` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/vue-jsx) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/vue-jsx?initialPath=__vitest__/) |
| `vue` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/vue) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/vue?initialPath=__vitest__/) |
| `vue2` | [GitHub](https://github.com/vitest-dev/vitest/tree/main/examples/vue2) | [Play Online](https://stackblitz.com/fork/github/vitest-dev/vitest/tree/main/examples/vue2?initialPath=__vitest__/) |


Projects using Vitest
---------------------


* [unocss](https://github.com/unocss/unocss)
* [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import)
* [unplugin-vue-components](https://github.com/antfu/unplugin-vue-components)
* [vue](https://github.com/vuejs/core)
* [vite](https://github.com/vitejs/vite)
* [vitesse](https://github.com/antfu/vitesse)
* [vitesse-lite](https://github.com/antfu/vitesse-lite)
* [fluent-vue](https://github.com/demivan/fluent-vue)
* [vueuse](https://github.com/vueuse/vueuse)
* [milkdown](https://github.com/Saul-Mirone/milkdown)
* [gridjs-svelte](https://github.com/iamyuu/gridjs-svelte)
* [spring-easing](https://github.com/okikio/spring-easing)
* [bytemd](https://github.com/bytedance/bytemd)
* [faker](https://github.com/faker-js/faker)
* [million](https://github.com/aidenybai/million)
* [Vitamin](https://github.com/wtchnm/Vitamin)
* [neodrag](https://github.com/PuruVJ/neodrag)
* [svelte-multiselect](https://github.com/janosh/svelte-multiselect)
* [iconify](https://github.com/iconify/iconify)
* [tdesign-vue-next](https://github.com/Tencent/tdesign-vue-next)
* [cz-git](https://github.com/Zhengqbbb/cz-git)


Using Unreleased Commits
------------------------


If you can't wait for a new release to test the latest features, you will need to clone the [vitest repo](https://github.com/vitest-dev/vitest) to your local machine and then build and link it yourself ([pnpm](https://pnpm.io/) is required):



bash
```
git clone https://github.com/vitest-dev/vitest.git
cd vitest
pnpm install
cd packages/vitest
pnpm run build
pnpm link --global # you can use your preferred package manager for this step
```


```
git clone https://github.com/vitest-dev/vitest.git
cd vitest
pnpm install
cd packages/vitest
pnpm run build
pnpm link --global # you can use your preferred package manager for this step
```


Then go to the project where you are using Vitest and run `pnpm link --global vitest` (or the package manager that you used to link `vitest` globally).


Community
---------


If you have questions or need help, reach out to the community at [Discord](https://chat.vitest.dev) and [GitHub Discussions](https://github.com/vitest-dev/vitest/discussions).



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/index.html>

Test Runner
===========



**WARNING**This is advanced API. If you are just running tests, you probably don't need this. It is primarily used by library authors.



You can specify a path to your test runner with the `runner` option in your configuration file. This file should have a default export with a class implementing these methods:



ts
```
export interface VitestRunner {
  /**
   * First thing that's getting called before actually collecting and running tests.
   */
  onBeforeCollect?(paths: string[]): unknown
  /**
   * Called after collecting tests and before "onBeforeRun".
   */
  onCollected?(files: File[]): unknown

  /**
   * Called when test runner should cancel next test runs.
   * Runner should listen for this method and mark tests and suites as skipped in
   * "onBeforeRunSuite" and "onBeforeRunTest" when called.
   */
  onCancel?(reason: CancelReason): unknown

  /**
   * Called before running a single test. Doesn't have "result" yet.
   */
  onBeforeRunTest?(test: Test): unknown
  /**
   * Called before actually running the test function. Already has "result" with "state" and "startTime".
   */
  onBeforeTryTest?(test: Test, retryCount: number): unknown
  /**
   * Called after result and state are set.
   */
  onAfterRunTest?(test: Test): unknown
  /**
   * Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws.
   */
  onAfterTryTest?(test: Test, retryCount: number): unknown

  /**
   * Called before running a single suite. Doesn't have "result" yet.
   */
  onBeforeRunSuite?(suite: Suite): unknown
  /**
   * Called after running a single suite. Has state and result.
   */
  onAfterRunSuite?(suite: Suite): unknown

  /**
   * If defined, will be called instead of usual Vitest suite partition and handling.
   * "before" and "after" hooks will not be ignored.
   */
  runSuite?(suite: Suite): Promise<void>
  /**
   * If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function.
   * "before" and "after" hooks will not be ignored.
   */
  runTest?(test: Test): Promise<void>

  /**
   * Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests.
   */
  onTaskUpdate?(task: [string, TaskResult | undefined][]): Promise<void>

  /**
   * Called before running all tests in collected paths.
   */
  onBeforeRun?(files: File[]): unknown
  /**
   * Called right after running all tests in collected paths.
   */
  onAfterRun?(files: File[]): unknown
  /**
   * Called when new context for a test is defined. Useful, if you want to add custom properties to the context.
   * If you only want to define custom context with a runner, consider using "beforeAll" in "setupFiles" instead.
   */
  extendTestContext?(context: TestContext): TestContext
  /**
   * Called, when certain files are imported. Can be called in two situations: when collecting tests and when importing setup files.
   */
  importFile(filepath: string, source: VitestRunnerImportSource): unknown
  /**
   * Publicly available configuration.
   */
  config: VitestRunnerConfig
}
```


```
export interface VitestRunner {
  /**
   * First thing that's getting called before actually collecting and running tests.
   */
  onBeforeCollect?(paths: string[]): unknown
  /**
   * Called after collecting tests and before "onBeforeRun".
   */
  onCollected?(files: File[]): unknown

  /**
   * Called when test runner should cancel next test runs.
   * Runner should listen for this method and mark tests and suites as skipped in
   * "onBeforeRunSuite" and "onBeforeRunTest" when called.
   */
  onCancel?(reason: CancelReason): unknown

  /**
   * Called before running a single test. Doesn't have "result" yet.
   */
  onBeforeRunTest?(test: Test): unknown
  /**
   * Called before actually running the test function. Already has "result" with "state" and "startTime".
   */
  onBeforeTryTest?(test: Test, retryCount: number): unknown
  /**
   * Called after result and state are set.
   */
  onAfterRunTest?(test: Test): unknown
  /**
   * Called right after running the test function. Doesn't have new state yet. Will not be called, if the test function throws.
   */
  onAfterTryTest?(test: Test, retryCount: number): unknown

  /**
   * Called before running a single suite. Doesn't have "result" yet.
   */
  onBeforeRunSuite?(suite: Suite): unknown
  /**
   * Called after running a single suite. Has state and result.
   */
  onAfterRunSuite?(suite: Suite): unknown

  /**
   * If defined, will be called instead of usual Vitest suite partition and handling.
   * "before" and "after" hooks will not be ignored.
   */
  runSuite?(suite: Suite): Promise<void>
  /**
   * If defined, will be called instead of usual Vitest handling. Useful, if you have your custom test function.
   * "before" and "after" hooks will not be ignored.
   */
  runTest?(test: Test): Promise<void>

  /**
   * Called, when a task is updated. The same as "onTaskUpdate" in a reporter, but this is running in the same thread as tests.
   */
  onTaskUpdate?(task: [string, TaskResult | undefined][]): Promise<void>

  /**
   * Called before running all tests in collected paths.
   */
  onBeforeRun?(files: File[]): unknown
  /**
   * Called right after running all tests in collected paths.
   */
  onAfterRun?(files: File[]): unknown
  /**
   * Called when new context for a test is defined. Useful, if you want to add custom properties to the context.
   * If you only want to define custom context with a runner, consider using "beforeAll" in "setupFiles" instead.
   */
  extendTestContext?(context: TestContext): TestContext
  /**
   * Called, when certain files are imported. Can be called in two situations: when collecting tests and when importing setup files.
   */
  importFile(filepath: string, source: VitestRunnerImportSource): unknown
  /**
   * Publicly available configuration.
   */
  config: VitestRunnerConfig
}
```


When initiating this class, Vitest passes down Vitest config, - you should expose it as a `config` property.



**WARNING**Vitest also injects an instance of `ViteNodeRunner` as `__vitest_executor` property. You can use it to process files in `importFile` method (this is default behavior of `TestRunner` and `BenchmarkRunner`).


`ViteNodeRunner` exposes `executeId` method, which is used to import test files in a Vite-friendly environment. Meaning, it will resolve imports and transform file content at runtime so that Node can understand it.




**TIP**Snapshot support and some other features depend on the runner. If you don't want to lose it, you can extend your runner from `VitestTestRunner` imported from `vitest/runners`. It also exposes `BenchmarkNodeRunner`, if you want to extend benchmark functionality.



Your task function
------------------


You can extend Vitest task system with your tasks. A task is an object that is part of a suite. It is automatically added to the current suite with a `suite.custom` method:



js
```
// ./utils/custom.js
import { getCurrentSuite, setFn } from 'vitest/suite'

export { describe, beforeAll, afterAll } from 'vitest'

// this function will be called, when Vitest collects tasks
export const myCustomTask = function (name, fn) {
  const task = getCurrentSuite().custom(name)
  task.meta = {
    customPropertyToDifferentiateTask: true
  }
  setFn(task, fn || (() => {}))
}
```


```
// ./utils/custom.js
import { getCurrentSuite, setFn } from 'vitest/suite'

export { describe, beforeAll, afterAll } from 'vitest'

// this function will be called, when Vitest collects tasks
export const myCustomTask = function (name, fn) {
  const task = getCurrentSuite().custom(name)
  task.meta = {
    customPropertyToDifferentiateTask: true
  }
  setFn(task, fn || (() => {}))
}
```



js
```
// ./garden/tasks.test.js
import { afterAll, beforeAll, describe, myCustomTask } from '../utils/custom.js'
import { gardener } from './gardener.js'

describe('take care of the garden', () => {
  beforeAll(() => {
    gardener.putWorkingClothes()
  })

  myCustomTask('weed the grass', () => {
    gardener.weedTheGrass()
  })
  myCustomTask('water flowers', () => {
    gardener.waterFlowers()
  })

  afterAll(() => {
    gardener.goHome()
  })
})
```


```
// ./garden/tasks.test.js
import { afterAll, beforeAll, describe, myCustomTask } from '../utils/custom.js'
import { gardener } from './gardener.js'

describe('take care of the garden', () => {
  beforeAll(() => {
    gardener.putWorkingClothes()
  })

  myCustomTask('weed the grass', () => {
    gardener.weedTheGrass()
  })
  myCustomTask('water flowers', () => {
    gardener.waterFlowers()
  })

  afterAll(() => {
    gardener.goHome()
  })
})
```



bash
```
vitest ./garden/tasks.test.js
```


```
vitest ./garden/tasks.test.js
```



**WARNING**If you don't have a custom runner or didn't define `runTest` method, Vitest will try to retrieve a task automatically. If you didn't add a function with `setFn`, it will fail.




**TIP**Custom task system supports hooks and contexts. If you want to support property chaining (like, `only`, `skip`, and your custom ones), you can import `createChainable` from `vitest/suite` and wrap your function with it. You will need to call `custom` as `custom.call(this)`, if you decide to do this.




 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/advanced/runner.html>

Task Metadata
=============



**WARNING**Vitest exposes experimental private API. Breaking changes might not follow semver, please pin Vitest's version when using it.



If you are developing a custom reporter or using Vitest Node.js API, you might find it useful to pass data from tests that are being executed in various contexts to your reporter or custom Vitest handler.


To accomplish this, relying on the [test context](../guide/test-context) is not feasible since it cannot be serialized. However, with Vitest, you can utilize the `meta` property available on every task (suite or test) to share data between your tests and the Node.js process. It's important to note that this communication is one-way only, as the `meta` property can only be modified from within the test context. Any changes made within the Node.js context will not be visible in your tests.


You can populate `meta` property on test context or inside `beforeAll`/`afterAll` hooks for suite tasks.



ts
```
afterAll((suite) => {
  suite.meta.done = true
})

test('custom', ({ task }) => {
  task.meta.custom = 'some-custom-handler'
})
```


```
afterAll((suite) => {
  suite.meta.done = true
})

test('custom', ({ task }) => {
  task.meta.custom = 'some-custom-handler'
})
```


Once a test is completed, Vitest will send a task including the result and `meta` to the Node.js process using RPC. To intercept and process this task, you can utilize the `onTaskUpdate` method available in your reporter implementation:



ts
```
// custom-reporter.js
export default {
  // you can intercept packs if needed
  onTaskUpdate(packs) {
    const [id, result, meta] = packs[0]
  },
  // meta is located on every task inside "onFinished"
  onFinished(files) {
    files[0].meta.done === true
    files[0].tasks[0].meta.custom === 'some-custom-handler'
  }
}
```


```
// custom-reporter.js
export default {
  // you can intercept packs if needed
  onTaskUpdate(packs) {
    const [id, result, meta] = packs[0]
  },
  // meta is located on every task inside "onFinished"
  onFinished(files) {
    files[0].meta.done === true
    files[0].tasks[0].meta.custom === 'some-custom-handler'
  }
}
```



**WARNING**Vitest can send several tasks at the same time if several tests are completed in a short period of time.




**BEWARE**Vitest uses different methods to communicate with the Node.js process.


* If Vitest runs tests inside worker threads, it will send data via [message port](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort)
* If Vitest uses child process, the data will be send as a serialized Buffer via [`process.send`](https://nodejs.org/api/process.html#processsendmessage-sendhandle-options-callback) API
* If Vitest run tests in the browser, the data will be stringified using [flatted](https://www.npmjs.com/package/flatted) package


The general rule of thumb is that you can send almost anything, except for functions, Promises, regexp (`v8.stringify` cannot serialize it, but you can send a string version and parse it in the Node.js process yourself), and other non-serializable data, but you can have cyclic references inside.


Also, make sure you serialize [Error properties](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#error_types) before you set them.



You can also get this information from Vitest state when tests finished running:



ts
```
const vitest = await createVitest('test')
await vitest.start()
vitest.state.getFiles()[0].meta.done === true
vitest.state.getFiles()[0].tasks[0].meta.custom === 'some-custom-handler'
```


```
const vitest = await createVitest('test')
await vitest.start()
vitest.state.getFiles()[0].meta.done === true
vitest.state.getFiles()[0].tasks[0].meta.custom === 'some-custom-handler'
```


It's also possible to extend type definitions when using TypeScript:



ts
```
declare module 'vitest' {
  interface TaskMeta {
    done?: boolean
    custom?: string
  }
}
```


```
declare module 'vitest' {
  interface TaskMeta {
    done?: boolean
    custom?: string
  }
}
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/advanced/metadata.html>

Workspace
=========


Vitest provides built-in support for monorepositories through a workspace configuration file. You can create a workspace to define your project's setups.


Defining a workspace
--------------------


A workspace should have a `vitest.workspace` or `vitest.projects` file in its root (in the same folder as your config file if you have one). Vitest supports `ts`/`js`/`json` extensions for this file.


Workspace configuration file should have a default export with a list of files or glob patterns referencing your projects. For example, if you have a folder with your projects named `packages`, you can define a workspace with this config file:




vitest.workspace.ts


ts
```
export default [
  'packages/*'
]
```


```
export default [
  'packages/*'
]
```



Vitest will consider every folder in `packages` as a separate project even if it doesn't have a config file inside.



**WARNING**Vitest will not consider the root config as a workspace project (so it will not run tests specified in `include`) unless it is specified in this config.



You can also reference projects with their config files:




vitest.workspace.ts


ts
```
export default [
  'packages/*/vitest.config.{e2e,unit}.ts'
]
```


```
export default [
  'packages/*/vitest.config.{e2e,unit}.ts'
]
```



This pattern will only include projects with `vitest.config` file that includes `e2e` and `unit` before the extension.



**WARNING**If you are referencing filenames with glob pattern, make sure your config file starts with `vite.config` or `vitest.config`. Otherwise Vitest will skip it.



You can also define projects with inline config. Workspace file supports using both syntaxes at the same time.




vitest.workspace.ts


ts
```
import { defineWorkspace } from 'vitest/config'

// defineWorkspace provides a nice type hinting DX
export default defineWorkspace([
  'packages/*',
  {
    // add "extends" to merge two configs together
    extends: './vite.config.js',
    test: {
      include: ['tests/**/*.{browser}.test.{ts,js}'],
      // it is recommended to define a name when using inline configs
      name: 'happy-dom',
      environment: 'happy-dom',
    }
  },
  {
    test: {
      include: ['tests/**/*.{node}.test.{ts,js}'],
      name: 'node',
      environment: 'node',
    }
  }
])
```


```
import { defineWorkspace } from 'vitest/config'

// defineWorkspace provides a nice type hinting DX
export default defineWorkspace([
  'packages/*',
  {
    // add "extends" to merge two configs together
    extends: './vite.config.js',
    test: {
      include: ['tests/**/*.{browser}.test.{ts,js}'],
      // it is recommended to define a name when using inline configs
      name: 'happy-dom',
      environment: 'happy-dom',
    }
  },
  {
    test: {
      include: ['tests/**/*.{node}.test.{ts,js}'],
      name: 'node',
      environment: 'node',
    }
  }
])
```




**WARNING**All projects should have unique names. Otherwise, Vitest will throw an error. If you do not provide a name inside the inline config, Vitest will assign a number. If you don't provide a name inside a project config defined with glob syntax, Vitest will use the directory name by default.



If you don't rely on inline configs, you can just create a small json file in your root directory:




vitest.workspace.json


json
```
[
  "packages/*"
]
```


```
[
  "packages/*"
]
```



Workspace projects don't support all configuration properties. For better type safety, use `defineProject` instead of `defineConfig` method inside project configuration files:




packages/a/vitest.config.ts


ts
```
import { defineProject } from 'vitest/config'

export default defineProject({
  test: {
    environment: 'jsdom',
    // "reporters" is not supported in a project config,
    // so it will show an error
    reporters: ['json']
  }
})
```


```
import { defineProject } from 'vitest/config'

export default defineProject({
  test: {
    environment: 'jsdom',
    // "reporters" is not supported in a project config,
    // so it will show an error
    reporters: ['json']
  }
})
```



Configuration
-------------


None of the configuration options are inherited from the root-level config file. You can create a shared config file and merge it with the project config yourself:




packages/a/vitest.config.ts


ts
```
import { defineProject, mergeConfig } from 'vitest/config'
import configShared from '../vitest.shared.js'

export default mergeConfig(
  configShared,
  defineProject({
    test: {
      environment: 'jsdom',
    }
  })
)
```


```
import { defineProject, mergeConfig } from 'vitest/config'
import configShared from '../vitest.shared.js'

export default mergeConfig(
  configShared,
  defineProject({
    test: {
      environment: 'jsdom',
    }
  })
)
```



Also, some of the configuration options are not allowed in a project config. Most notably:


* `coverage`: coverage is done for the whole workspace
* `reporters`: only root-level reporters can be supported
* `resolveSnapshotPath`: only root-level resolver is respected
* all other options that don't affect test runners



**TIP**All configuration options that are not supported inside a project config have  \*  sign next them in ["Config"](../config/index) page.



Coverage
--------


Coverage for workspace projects works out of the box. But if you have [`all`](../config/index#coverage-all) option enabled and use non-conventional extensions in some of your projects, you will need to have a plugin that handles this extension in your root configuration file.


For example, if you have a package that uses Vue files and it has its own config file, but some of the files are not imported in your tests, coverage will fail trying to analyze the usage of unused files, because it relies on the root configuration rather than project configuration.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/workspace>

Command Line Interface
======================


Commands
--------


### 
`vitest`


Start Vitest in the current directory. Will enter the watch mode in development environment and run mode in CI automatically.


You can pass an additional argument as the filter of the test files to run. For example:



bash
```
vitest foobar
```


```
vitest foobar
```


Will run only the test file that contains `foobar` in their paths. This filter only checks inclusion and doesn't support regexp or glob patterns (unless your terminal processes it before Vitest receives the filter).


### 
`vitest run`


Perform a single run without watch mode.


### 
`vitest watch`


Run all test suites but watch for changes and rerun tests when they change. Same as calling `vitest` without an argument. Will fallback to `vitest run` in CI.


### 
`vitest dev`


Alias to `vitest watch`.


### 
`vitest related`


Run only tests that cover a list of source files. Works with static imports (e.g., `import('./index.ts')` or `import index from './index.ts`), but not the dynamic ones (e.g., `import(filepath)`). All files should be relative to root folder.


Useful to run with [`lint-staged`](https://github.com/okonet/lint-staged) or with your CI setup.



bash
```
vitest related /src/index.ts /src/hello-world.js
```


```
vitest related /src/index.ts /src/hello-world.js
```



**TIP**Don't forget that Vitest runs with enabled watch mode by default. If you are using tools like `lint-staged`, you should also pass `--run` option, so that command can exit normally.



js
```
// .lintstagedrc.js
export default {
  '*.{js,ts}': 'vitest related --run',
}
```


```
// .lintstagedrc.js
export default {
  '*.{js,ts}': 'vitest related --run',
}
```



### 
`vitest bench`


Run only [benchmark](features#benchmarking-experimental) tests, which compare performance results.


Options
-------




| Options |  |
| --- | --- |
| `-v, --version` | Display version number |
| `-r, --root <path>` | Define the project root |
| `-c, --config <path>` | Path to config file |
| `-u, --update` | Update snapshots |
| `-w, --watch` | Smart & instant watch mode |
| `-t, --testNamePattern <pattern>` | Run tests with full names matching the pattern |
| `--dir <path>` | Base directory to scan for the test files |
| `--ui` | Enable UI |
| `--open` | Open the UI automatically if enabled (default: `true`) |
| `--api [api]` | Serve API, available options: `--api.port <port>`, `--api.host [host]` and `--api.strictPort` |
| `--threads` | Enable Threads (default: `true`) |
| `--silent` | Silent console output from tests |
| `--isolate` | Isolate environment for each test file (default: `true`) |
| `--reporter <name>` | Select reporter: `default`, `verbose`, `dot`, `junit`, `json`, or a path to a custom reporter |
| `--outputFile <filename/-s>` | Write test results to a file when the `--reporter=json` or `--reporter=junit` option is also specified  Via [cac's dot notation](https://github.com/cacjs/cac#dot-nested-options) you can specify individual outputs for multiple reporters |
| `--coverage` | Enable coverage report |
| `--run` | Do not watch |
| `--mode` | Override Vite mode (default: `test`) |
| `--mode <name>` | Override Vite mode (default: `test`) |
| `--globals` | Inject APIs globally |
| `--dom` | Mock browser api with happy-dom |
| `--browser [options]` | Run tests in [the browser](browser) (default: `false`) |
| `--environment <env>` | Runner environment (default: `node`) |
| `--passWithNoTests` | Pass when no tests found |
| `--logHeapUsage` | Show the size of heap for each test |
| `--allowOnly` | Allow tests and suites that are marked as `only` (default: false in CI, true otherwise) |
| `--dangerouslyIgnoreUnhandledErrors` | Ignore any unhandled errors that occur |
| `--changed [since]` | Run tests that are affected by the changed files (default: false). See [docs](#changed) |
| `--shard <shard>` | Execute tests in a specified shard |
| `--sequence` | Define in what order to run tests. Use [cac's dot notation](https://github.com/cacjs/cac#dot-nested-options) to specify options (for example, use `--sequence.shuffle` to run tests in random order) |
| `--no-color` | Removes colors from the console output |
| `--inspect` | Enables Node.js inspector |
| `--inspect-brk` | Enables Node.js inspector with break |
| `--bail <number>` | Stop test execution when given number of tests have failed |
| `--retry <times>` | Retry the test specific number of times if it fails |
| `-h, --help` | Display available CLI options |



**TIP**Vitest supports both camel case and kebab case for CLI arguments. For example, `--passWithNoTests` and `--pass-with-no-tests` will both work (`--no-color` and `--inspect-brk` are the exceptions).


Vitest also supports different ways of specifying the value: `--reporter dot` and `--reporter=dot` are both valid.


If option supports an array of values, you need to pass the option multiple times:




```
vitest --reporter=dot --reporter=default
```


```
vitest --reporter=dot --reporter=default
```


Boolean options can be negated with `no-` prefix. Specifying the value as `false` also works:




```
vitest --no-api
vitest --api=false
```


```
vitest --no-api
vitest --api=false
```



### changed


* **Type**: `boolean | string`
* **Default**: false


Run tests only against changed files. If no value is provided, it will run tests against uncommitted changes (including staged and unstaged).


To run tests against changes made in the last commit, you can use `--changed HEAD~1`. You can also pass commit hash or branch name.


If paired with the `forceRerunTriggers` config option it will run the whole test suite if a match is found.


### shard


* **Type**: `string`
* **Default**: disabled


Test suite shard to execute in a format of `<index>`/`<count>`, where


	+ `count` is a positive integer, count of divided parts
	+ `index` is a positive integer, index of divided partThis command will divide all tests into `count` equal parts, and will run only those that happen to be in an `index` part. For example, to split your tests suite into three parts, use this:



sh
```
vitest run --shard=1/3
vitest run --shard=2/3
vitest run --shard=3/3
```


```
vitest run --shard=1/3
vitest run --shard=2/3
vitest run --shard=3/3
```



**WARNING**You cannot use this option with `--watch` enabled (enabled in dev by default).




 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/cli.html>

Configuring Vitest
==================


Configuration
-------------


`vitest` will read your root `vite.config.ts` when it is present to match with the plugins and setup as your Vite app. If you want to have a different configuration for testing or your main app doesn't rely on Vite specifically, you could either:


* Create `vitest.config.ts`, which will have the higher priority and will override the configuration from `vite.config.ts`
* Pass `--config` option to CLI, e.g. `vitest --config ./path/to/vitest.config.ts`
* Use `process.env.VITEST` or `mode` property on `defineConfig` (will be set to `test`/`benchmark` if not overridden) to conditionally apply different configuration in `vite.config.ts`


To configure `vitest` itself, add `test` property in your Vite config. You'll also need to add a reference to Vitest types using a [triple slash command](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types-) at the top of your config file, if you are importing `defineConfig` from `vite` itself.


using `defineConfig` from `vite` you should follow this:



ts
```
/// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    // ...
  },
})
```


```
/// <reference types="vitest" />
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    // ...
  },
})
```


using `defineConfig` from `vitest/config` you should follow this:



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    // ...
  },
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    // ...
  },
})
```


You can retrieve Vitest's default options to expand them if needed:



ts
```
import { configDefaults, defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    exclude: [...configDefaults.exclude, 'packages/template/*'],
  },
})
```


```
import { configDefaults, defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    exclude: [...configDefaults.exclude, 'packages/template/*'],
  },
})
```


When using a separate `vitest.config.js`, you can also extend Vite's options from another config file if needed:



ts
```
import { defineConfig, mergeConfig } from 'vitest/config'
import viteConfig from './vite.config'

export default mergeConfig(viteConfig, defineConfig({
  test: {
    exclude: ['packages/template/*'],
  },
}))
```


```
import { defineConfig, mergeConfig } from 'vitest/config'
import viteConfig from './vite.config'

export default mergeConfig(viteConfig, defineConfig({
  test: {
    exclude: ['packages/template/*'],
  },
}))
```



**WARNING**`mergeConfig` helper is availabe in Vitest since v0.30.0. You can import it from `vite` directly, if you use lower version.



Options
-------



**TIP**In addition to the following options, you can also use any configuration option from [Vite](https://vitejs.dev/config/). For example, `define` to define global variables, or `resolve.alias` to define aliases.




**TIP**All configuration options that are not supported inside a [workspace](../guide/workspace) project config have  \*  sign next to them.



### include


* **Type:** `string[]`
* **Default:** `['**/__tests__/**/*.?(c|m)[jt]s?(x)', '**/?(*.){test,spec}.?(c|m)[jt]s?(x)']`


Files to include in the test run, using glob pattern.


### exclude


* **Type:** `string[]`
* **Default:** `['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**', '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*']`


Files to exclude from the test run, using glob pattern.


### includeSource


* **Type:** `string[]`
* **Default:** `[]`


Include globs for in-source test files.


When defined, Vitest will run all matched files with `import.meta.vitest` inside.


### deps


* **Type:** `{ external?, inline?, ... }`


Handling for dependencies resolution.


#### deps.experimentalOptimizer


* **Type:** `{ ssr?, web? }`
* **Version:** Since Vitest 0.29.0
* **See also:** [Dep Optimization Options](https://vitejs.dev/config/dep-optimization-options.html)


Enable dependency optimization. If you have a lot of tests, this might improve their performance.


When Vitest encounters the external library listed in `include`, it will be bundled into a single file using esbuild and imported as a whole module. This is good for several reasons:


* Importing packages with a lot of imports is expensive. By bundling them into one file we can save a lot of time
* Importing UI libraries is expensive because they are not meant to run inside Node.js
* Your `alias` configuration is now respected inside bundled packages
* Code in your tests is running closer to how it's running in the browser


Be aware that only packages in `deps.experimentalOptimizer?.[mode].include` option are bundled (some plugins populate this automatically, like Svelte). You can read more about available options in [Vite](https://vitejs.dev/config/dep-optimization-options.html) docs. By default, Vitest uses `experimentalOptimizer.web` for `jsdom` and `happy-dom` environments, and `experimentalOptimizer.ssr` for `node` and `edge` environments, but it is configurable by [`transformMode`](#transformmode).


This options also inherits your `optimizeDeps` configuration (for web Vitest will extend `optimizeDeps`, for ssr - `ssr.optimizeDeps`). If you redefine `include`/`exclude` option in `deps.experimentalOptimizer` it will extend your `optimizeDeps` when running tests. Vitest automatically removes the same options from `include`, if they are listed in `exclude`.



**TIP**You will not be able to edit your `node_modules` code for debugging, since the code is actually located in your `cacheDir` or `test.cache.dir` directory. If you want to debug with `console.log` statements, edit it directly or force rebundling with `deps.experimentalOptimizer?.[mode].force` option.



#### deps.external


* **Type:** `(string | RegExp)[]`
* **Default:** `['**/node_modules/**']`


Externalize means that Vite will bypass the package to native Node. Externalized dependencies will not be applied Vite's transformers and resolvers, so they do not support HMR on reload. Typically, packages under `node_modules` are externalized.


#### deps.inline


* **Type:** `(string | RegExp)[] | true`
* **Default:** `[]`


Vite will process inlined modules. This could be helpful to handle packages that ship `.js` in ESM format (that Node can't handle).


If `true`, every dependency will be inlined. All dependencies, specified in [`ssr.noExternal`](https://vitejs.dev/guide/ssr.html#ssr-externals) will be inlined by default.


#### deps.fallbackCJS


* **Type** `boolean`
* **Default:** `false`


When a dependency is a valid ESM package, try to guess the cjs version based on the path. This might be helpful, if a dependency has the wrong ESM file.


This might potentially cause some misalignment if a package has different logic in ESM and CJS mode.


#### deps.registerNodeLoader \*


* **Type:** `boolean`
* **Default:** `false`


Use [experimental Node loader](https://nodejs.org/api/esm.html#loaders) to resolve imports inside externalized files, using Vite resolve algorithm.


If disabled, your `alias` and `<plugin>.resolveId` won't affect imports inside externalized packages (by default, `node_modules`).


#### deps.interopDefault


* **Type:** `boolean`
* **Default:** `true`


Interpret CJS module's default as named exports. Some dependencies only bundle CJS modules and don't use named exports that Node.js can statically analyze when a package is imported using `import` syntax instead of `require`. When importing such dependencies in Node environment using named exports, you will see this error:




```
import { read } from 'fs-jetpack';
         ^^^^
SyntaxError: Named export 'read' not found. The requested module 'fs-jetpack' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export.
```


```
import { read } from 'fs-jetpack';
         ^^^^
SyntaxError: Named export 'read' not found. The requested module 'fs-jetpack' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export.
```


Vitest doesn't do static analysis, and cannot fail before your running code, so you will most likely see this error when running tests, if this feature is disabled:




```
TypeError: createAsyncThunk is not a function
TypeError: default is not a function
```


```
TypeError: createAsyncThunk is not a function
TypeError: default is not a function
```


By default, Vitest assumes you are using a bundler to bypass this and will not fail, but you can disable this behaviour manually, if you code is not processed.


#### deps.moduleDirectories


* **Type:** `string[]`
* **Default**: `['node_modules']`


A list of directories that should be treated as module directories. This config option affects the behavior of [`vi.mock`](../api/vi#vi-mock): when no factory is provided and the path of what you are mocking matches one of the `moduleDirectories` values, Vitest will try to resolve the mock by looking for a `__mocks__` folder in the [root](index#root) of the project.


This option will also affect if a file should be treated as a module when externalizing dependencies. By default, Vitest imports external modules with native Node.js bypassing Vite transformation step.


Setting this option will *override* the default, if you wish to still search `node_modules` for packages include it along with any other options:



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    deps: {
      moduleDirectories: ['node_modules', path.resolve('../../packages')],
    }
  },
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    deps: {
      moduleDirectories: ['node_modules', path.resolve('../../packages')],
    }
  },
})
```


### runner


* **Type**: `VitestRunnerConstructor`
* **Default**: `node`, when running tests, or `benchmark`, when running benchmarks


Path to a custom test runner. This is an advanced feature and should be used with custom library runners. You can read more about it in [the documentation](../advanced/runner).


### benchmark


* **Type:** `{ include?, exclude?, ... }`


Options used when running `vitest bench`.


#### benchmark.include


* **Type:** `string[]`
* **Default:** `['**/*.{bench,benchmark}.?(c|m)[jt]s?(x)']`


Include globs for benchmark test files


#### benchmark.exclude


* **Type:** `string[]`
* **Default:** `['node_modules', 'dist', '.idea', '.git', '.cache']`


Exclude globs for benchmark test files


#### benchmark.includeSource


* **Type:** `string[]`
* **Default:** `[]`


Include globs for in-source benchmark test files. This option is similar to [`includeSource`](#includesource).


When defined, Vitest will run all matched files with `import.meta.vitest` inside.


#### benchmark.reporters


* **Type:** `Arrayable<BenchmarkBuiltinReporters | Reporter>`
* **Default:** `'default'`


Custom reporter for output. Can contain one or more built-in report names, reporter instances, and/or paths to custom reporters.


#### benchmark.outputFile


* **Type:** `string | Record<string, string>`


Write benchmark results to a file when the `--reporter=json` option is also specified. By providing an object instead of a string you can define individual outputs when using multiple reporters.


To provide object via CLI command, use the following syntax: `--outputFile.json=./path --outputFile.junit=./other-path`.


### alias


* **Type:** `Record<string, string> | Array<{ find: string | RegExp, replacement: string, customResolver?: ResolverFunction | ResolverObject }>`


Define custom aliases when running inside tests. They will be merged with aliases from `resolve.alias`.


### globals


* **Type:** `boolean`
* **Default:** `false`
* **CLI:** `--globals`, `--globals=false`


By default, `vitest` does not provide global APIs for explicitness. If you prefer to use the APIs globally like Jest, you can pass the `--globals` option to CLI or add `globals: true` in the config.



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    globals: true,
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    globals: true,
  },
})
```


To get TypeScript working with the global APIs, add `vitest/globals` to the `types` field in your `tsconfig.json`



json
```
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}
```


```
// tsconfig.json
{
  "compilerOptions": {
    "types": ["vitest/globals"]
  }
}
```


If you are already using [`unplugin-auto-import`](https://github.com/antfu/unplugin-auto-import) in your project, you can also use it directly for auto importing those APIs.



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    AutoImport({
      imports: ['vitest'],
      dts: true, // generate TypeScript declaration
    }),
  ],
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    AutoImport({
      imports: ['vitest'],
      dts: true, // generate TypeScript declaration
    }),
  ],
})
```


### environment


* **Type:** `'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' | string`
* **Default:** `'node'`
* **CLI:** `--environment=<env>`


The environment that will be used for testing. The default environment in Vitest is a Node.js environment. If you are building a web application, you can use browser-like environment through either [`jsdom`](https://github.com/jsdom/jsdom) or [`happy-dom`](https://github.com/capricorn86/happy-dom) instead. If you are building edge functions, you can use [`edge-runtime`](https://edge-runtime.vercel.app/packages/vm) environment


By adding a `@vitest-environment` docblock or comment at the top of the file, you can specify another environment to be used for all tests in that file:


Docblock style:



js
```
/**
 * @vitest-environment jsdom
 */

test('use jsdom in this test file', () => {
  const element = document.createElement('div')
  expect(element).not.toBeNull()
})
```


```
/**
 * @vitest-environment jsdom
 */

test('use jsdom in this test file', () => {
  const element = document.createElement('div')
  expect(element).not.toBeNull()
})
```


Comment style:



js
```
// @vitest-environment happy-dom

test('use happy-dom in this test file', () => {
  const element = document.createElement('div')
  expect(element).not.toBeNull()
})
```


```
// @vitest-environment happy-dom

test('use happy-dom in this test file', () => {
  const element = document.createElement('div')
  expect(element).not.toBeNull()
})
```


For compatibility with Jest, there is also a `@jest-environment`:



js
```
/**
 * @jest-environment jsdom
 */

test('use jsdom in this test file', () => {
  const element = document.createElement('div')
  expect(element).not.toBeNull()
})
```


```
/**
 * @jest-environment jsdom
 */

test('use jsdom in this test file', () => {
  const element = document.createElement('div')
  expect(element).not.toBeNull()
})
```


If you are running Vitest with [`--threads=false`](#threads) flag, your tests will be run in this order: `node`, `jsdom`, `happy-dom`, `edge-runtime`, `custom environments`. Meaning, that every test with the same environment is grouped together, but is still running sequentially.


Starting from 0.23.0, you can also define custom environment. When non-builtin environment is used, Vitest will try to load package `vitest-environment-${name}`. That package should export an object with the shape of `Environment`:



ts
```
import type { Environment } from 'vitest'

export default <Environment>{
  name: 'custom',
  setup() {
    // custom setup
    return {
      teardown() {
        // called after all tests with this env have been run
      }
    }
  }
}
```


```
import type { Environment } from 'vitest'

export default <Environment>{
  name: 'custom',
  setup() {
    // custom setup
    return {
      teardown() {
        // called after all tests with this env have been run
      }
    }
  }
}
```


Vitest also exposes `builtinEnvironments` through `vitest/environments` entry, in case you just want to extend it. You can read more about extending environments in [our guide](../guide/environment).


### environmentOptions


* **Type:** `Record<'jsdom' | string, unknown>`
* **Default:** `{}`


These options are passed down to `setup` method of current [`environment`](#environment). By default, you can configure only JSDOM options, if you are using it as your test environment.


### environmentMatchGlobs


* **Type:** `[string, EnvironmentName][]`
* **Default:** `[]`


Automatically assign environment based on globs. The first match will be used.


For example:



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environmentMatchGlobs: [
      // all tests in tests/dom will run in jsdom
      ['tests/dom/**', 'jsdom'],
      // all tests in tests/ with .edge.test.ts will run in edge-runtime
      ['**\/*.edge.test.ts', 'edge-runtime'],
      // ...
    ]
  }
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environmentMatchGlobs: [
      // all tests in tests/dom will run in jsdom
      ['tests/dom/**', 'jsdom'],
      // all tests in tests/ with .edge.test.ts will run in edge-runtime
      ['**\/*.edge.test.ts', 'edge-runtime'],
      // ...
    ]
  }
})
```


### poolMatchGlobs


* **Type:** `[string, 'browser' | 'threads' | 'child_process'][]`
* **Default:** `[]`
* **Version:** Since Vitest 0.29.4


Automatically assign pool in which tests will run based on globs. The first match will be used.


For example:



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    poolMatchGlobs: [
      // all tests in "worker-specific" directory will run inside a worker as if you enabled `--threads` for them,
      ['**/tests/worker-specific/**', 'threads'],
      // run all tests in "browser" directory in an actual browser
      ['**/tests/browser/**', 'browser'],
      // all other tests will run based on "browser.enabled" and "threads" options, if you didn't specify other globs
      // ...
    ]
  }
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    poolMatchGlobs: [
      // all tests in "worker-specific" directory will run inside a worker as if you enabled `--threads` for them,
      ['**/tests/worker-specific/**', 'threads'],
      // run all tests in "browser" directory in an actual browser
      ['**/tests/browser/**', 'browser'],
      // all other tests will run based on "browser.enabled" and "threads" options, if you didn't specify other globs
      // ...
    ]
  }
})
```


### update \*


* **Type:** `boolean`
* **Default:** `false`
* **CLI:** `-u`, `--update`, `--update=false`


Update snapshot files. This will update all changed snapshots and delete obsolete ones.


### watch \*


* **Type:** `boolean`
* **Default:** `true`
* **CLI:** `-w`, `--watch`, `--watch=false`


Enable watch mode


### root


* **Type:** `string`
* **CLI:** `-r <path>`, `--root=<path>`


Project root


### reporters \*


* **Type:** `Reporter | Reporter[]`
* **Default:** `'default'`
* **CLI:** `--reporter=<name>`, `--reporter=<name1> --reporter=<name2>`


Custom reporters for output. Reporters can be [a Reporter instance](https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/types/reporter.ts) or a string to select built in reporters:


* `'default'` - collapse suites when they pass
* `'basic'` - give a reporter like default reporter in ci
* `'verbose'` - keep the full task tree visible
* `'dot'` - show each task as a single dot
* `'junit'` - JUnit XML reporter (you can configure `testsuites` tag name with `VITEST_JUNIT_SUITE_NAME` environmental variable)
* `'json'` - give a simple JSON summary
* `'html'` - outputs HTML report based on [`@vitest/ui`](../guide/ui)
* `'hanging-process'` - displays a list of hanging processes, if Vitest cannot exit process safely. This might be a heavy operation, enable it only if Vitest consistently cannot exit process
* path of a custom reporter (e.g. `'./path/to/reporter.ts'`, `'@scope/reporter'`)


### outputFile \*


* **Type:** `string | Record<string, string>`
* **CLI:** `--outputFile=<path>`, `--outputFile.json=./path`


Write test results to a file when the `--reporter=json`, `--reporter=html` or `--reporter=junit` option is also specified. By providing an object instead of a string you can define individual outputs when using multiple reporters.


### threads


* **Type:** `boolean`
* **Default:** `true`
* **CLI:** `--threads`, `--threads=false`


Enable multi-threading using [tinypool](https://github.com/tinylibs/tinypool) (a lightweight fork of [Piscina](https://github.com/piscinajs/piscina)). Prior to Vitest 0.29.0, Vitest was still running tests inside worker thread, even if this option was disabled. Since 0.29.0, if this option is disabled, Vitest uses `child_process` to spawn a process to run tests inside, meaning you can use `process.chdir` and other API that was not available inside workers. If you want to revert to the previous behaviour, use `--single-thread` option instead.


Disabling this option also disables module isolation, meaning all tests with the same environment are running inside a single child process.


### singleThread


* **Type:** `boolean`
* **Default:** `false`
* **Version:** Since Vitest 0.29.0


Run all tests with the same environment inside a single worker thread. This will disable built-in module isolation (your source code or [inlined](#deps-inline) code will still be reevaluated for each test), but can improve test performance. Before Vitest 0.29.0 this was equivalent to using `--no-threads`.



**WARNING**Even though this option will force tests to run one after another, this option is different from Jest's `--runInBand`. Vitest uses workers not only for running tests in parallel, but also to provide isolation. By disabling this option, your tests will run sequentially, but in the same global context, so you must provide isolation yourself.


This might cause all sorts of issues, if you are relying on global state (frontend frameworks usually do) or your code relies on environment to be defined separately for each test. But can be a speed boost for your tests (up to 3 times faster), that don't necessarily rely on global state or can easily bypass that.



### maxThreads \*


* **Type:** `number`
* **Default:** *available CPUs*


Maximum number of threads. You can also use `VITEST_MAX_THREADS` environment variable.


### minThreads \*


* **Type:** `number`
* **Default:** *available CPUs*


Minimum number of threads. You can also use `VITEST_MIN_THREADS` environment variable.


### useAtomics \*


* **Type:** `boolean`
* **Default:** `false`
* **Version:** Since Vitest 0.28.3


Use Atomics to synchronize threads.


This can improve performance in some cases, but might cause segfault in older Node versions.


### testTimeout


* **Type:** `number`
* **Default:** `5000`
* **CLI:** `--test-timeout=5000`


Default timeout of a test in milliseconds


### hookTimeout


* **Type:** `number`
* **Default:** `10000`


Default timeout of a hook in milliseconds


### teardownTimeout \*


* **Type:** `number`
* **Default:** `10000`


Default timeout to wait for close when Vitest shuts down, in milliseconds


### silent \*


* **Type:** `boolean`
* **Default:** `false`
* **CLI:** `--silent`, `--silent=false`


Silent console output from tests


### setupFiles


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


Path to setup files. They will be run before each test file.



**INFO**Changing setup files will trigger rerun of all tests.



You can use `process.env.VITEST_POOL_ID` (integer-like string) inside to distinguish between threads (will always be `'1'`, if run with `threads: false`).



**TIP**Note, that if you are running [`--threads=false`](#threads), this setup file will be run in the same global scope multiple times. Meaning, that you are accessing the same global object before each test, so make sure you are not doing the same thing more than you need.



For example, you may rely on a global variable:



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

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

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

globalThis.resetBeforeEachTest = true
```


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

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

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

globalThis.resetBeforeEachTest = true
```


### globalSetup


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


Path to global setup files, relative to project root


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



**INFO**Multiple globalSetup files are possible. setup and teardown are executed sequentially with teardown in reverse order.




**WARNING**Beware that the global setup is run in a different global scope, so your tests don't have access to variables defined here.



### watchExclude \*


* **Type:** `string[]`
* **Default:** `['**/node_modules/**', '**/dist/**']`


Glob pattern of file paths to be ignored from triggering watch rerun.


### forceRerunTriggers \*


* **Type**: `string[]`
* **Default:** `['**/package.json/**', '**/vitest.config.*/**', '**/vite.config.*/**']`


Glob pattern of file paths that will trigger the whole suite rerun. When paired with the `--changed` argument will run the whole test suite if the trigger is found in the git diff.


Useful if you are testing calling CLI commands, because Vite cannot construct a module graph:



ts
```
test('execute a script', async () => {
  // Vitest cannot rerun this test, if content of `dist/index.js` changes
  await execa('node', ['dist/index.js'])
})
```


```
test('execute a script', async () => {
  // Vitest cannot rerun this test, if content of `dist/index.js` changes
  await execa('node', ['dist/index.js'])
})
```



**TIP**Make sure that your files are not excluded by `watchExclude`.



### isolate


* **Type:** `boolean`
* **Default:** `true`
* **CLI:** `--isolate`, `--isolate=false`


Isolate environment for each test file. Does not work if you disable [`--threads`](#threads).


### coverage \*


You can use [`v8`](https://v8.dev/blog/javascript-code-coverage), [`istanbul`](https://istanbul.js.org/) or [a custom coverage solution](../guide/coverage#custom-coverage-provider) for coverage collection.



**INFO**The `c8` provider is being replaced by the `v8` provider. It will be deprecated in the next major version.



You can provide coverage options to CLI with dot notation:



sh
```
npx vitest --coverage.enabled --coverage.provider=istanbul --coverage.all
```


```
npx vitest --coverage.enabled --coverage.provider=istanbul --coverage.all
```



**WARNING**If you are using coverage options with dot notation, don't forget to specify `--coverage.enabled`. Do not provide a single `--coverage` option in that case.



#### coverage.provider


* **Type:** `'c8' | 'v8' | 'istanbul' | 'custom'`
* **Default:** `'v8'`
* **CLI:** `--coverage.provider=<provider>`


Use `provider` to select the tool for coverage collection.


#### coverage.enabled


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.enabled`, `--coverage.enabled=false`


Enables coverage collection. Can be overridden using `--coverage` CLI option.


#### coverage.include


* **Type:** `string[]`
* **Default:** `['**']`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.include=<path>`, `--coverage.include=<path1> --coverage.include=<path2>`


List of files included in coverage as glob patterns


#### coverage.extension


* **Type:** `string | string[]`
* **Default:** `['.js', '.cjs', '.mjs', '.ts', '.mts', '.cts', '.tsx', '.jsx', '.vue', '.svelte']`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.extension=<extension>`, `--coverage.extension=<extension1> --coverage.extension=<extension2>`


#### coverage.exclude


* **Type:** `string[]`
* **Default:**



js
```
[
  'coverage/**',
  'dist/**',
  'packages/*/test?(s)/**',
  '**/*.d.ts',
  'cypress/**',
  'test?(s)/**',
  'test?(-*).?(c|m)[jt]s?(x)',
  '**/*{.,-}{test,spec}.?(c|m)[jt]s?(x)',
  '**/__tests__/**',
  '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
  '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}',
]
```


```
[
  'coverage/**',
  'dist/**',
  'packages/*/test?(s)/**',
  '**/*.d.ts',
  'cypress/**',
  'test?(s)/**',
  'test?(-*).?(c|m)[jt]s?(x)',
  '**/*{.,-}{test,spec}.?(c|m)[jt]s?(x)',
  '**/__tests__/**',
  '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',
  '**/.{eslint,mocha,prettier}rc.{?(c|m)js,yml}',
]
```


* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.exclude=<path>`, `--coverage.exclude=<path1> --coverage.exclude=<path2>`


List of files excluded from coverage as glob patterns.


#### coverage.all


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.all`, `--coverage.all=false`


Whether to include all files, including the untested ones into report.


#### coverage.clean


* **Type:** `boolean`
* **Default:** `true`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.clean`, `--coverage.clean=false`


Clean coverage results before running tests


#### coverage.cleanOnRerun


* **Type:** `boolean`
* **Default:** `true`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.cleanOnRerun`, `--coverage.cleanOnRerun=false`


Clean coverage report on watch rerun


#### coverage.reportsDirectory


* **Type:** `string`
* **Default:** `'./coverage'`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.reportsDirectory=<path>`


Directory to write coverage report to.


#### coverage.reporter


* **Type:** `string | string[] | [string, {}][]`
* **Default:** `['text', 'html', 'clover', 'json']`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.reporter=<reporter>`, `--coverage.reporter=<reporter1> --coverage.reporter=<reporter2>`


Coverage reporters to use. See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters. See [`@types/istanbul-reporter`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/276d95e4304b3670eaf6e8e5a7ea9e265a14e338/types/istanbul-reports/index.d.ts) for details about reporter specific options.


The reporter has three different types:


* A single reporter: `{ reporter: 'html' }`
* Multiple reporters without options: `{ reporter: ['html', 'json'] }`
* A single or multiple reporters with reporter options:
ts
```
{
  reporter: [
    ['lcov', { 'projectRoot': './src' }],
    ['json', { 'file': 'coverage.json' }],
    ['text']
  ]
}
```


```
{
  reporter: [
    ['lcov', { 'projectRoot': './src' }],
    ['json', { 'file': 'coverage.json' }],
    ['text']
  ]
}
```


Since Vitest 0.31.0, you can check your coverage report in Vitest UI: check [Vitest UI Coverage](../guide/coverage#vitest-ui) for more details.


#### coverage.reportOnFailure


* **Type:** `boolean`
* **Default:** `true`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.reportOnFailure`, `--coverage.reportOnFailure=false`
* **Version:** Since Vitest 0.31.2


Generate coverage report even when tests fail.


#### coverage.skipFull


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.skipFull`, `--coverage.skipFull=false`


Do not show files with 100% statement, branch, and function coverage.


#### coverage.perFile


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.perFile`, `--coverage.perFile=false`


Check thresholds per file. See `lines`, `functions`, `branches` and `statements` for the actual thresholds.


#### coverage.thresholdAutoUpdate


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.thresholdAutoUpdate=<boolean>`


Update threshold values `lines`, `functions`, `branches` and `statements` to configuration file when current coverage is above the configured thresholds. This option helps to maintain thresholds when coverage is improved.


#### coverage.lines


* **Type:** `number`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.lines=<number>`


Threshold for lines. See [istanbul documentation](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information.


#### coverage.functions


* **Type:** `number`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.functions=<number>`


Threshold for functions. See [istanbul documentation](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information.


#### coverage.branches


* **Type:** `number`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.branches=<number>`


Threshold for branches. See [istanbul documentation](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information.


#### coverage.statements


* **Type:** `number`
* **Available for providers:** `'c8' | 'v8' | 'istanbul'`
* **CLI:** `--coverage.statements=<number>`


Threshold for statements. See [istanbul documentation](https://github.com/istanbuljs/nyc#coverage-thresholds) for more information.


#### coverage.allowExternal


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8'`
* **CLI:** `--coverage.allowExternal`, `--coverage.allowExternal=false`


Allow files from outside of your cwd.


#### coverage.excludeNodeModules


* **Type:** `boolean`
* **Default:** `true`
* **Available for providers:** `'c8'`
* **CLI:** `--coverage.excludeNodeModules`, `--coverage.excludeNodeModules=false`


Exclude coverage under `/node_modules/`.


#### coverage.src


* **Type:** `string[]`
* **Default:** `process.cwd()`
* **Available for providers:** `'c8'`
* **CLI:** `--coverage.src=<path>`


Specifies the directories that are used when `--all` is enabled.


#### coverage.100


* **Type:** `boolean`
* **Default:** `false`
* **Available for providers:** `'c8' | 'v8'`
* **CLI:** `--coverage.100`, `--coverage.100=false`


Shortcut for `--check-coverage --lines 100 --functions 100 --branches 100 --statements 100`.


#### coverage.ignoreClassMethods


* **Type:** `string[]`
* **Default:** `[]`
* **Available for providers:** `'istanbul'`
* **CLI:** `--coverage.ignoreClassMethods=<method>`


Set to array of class method names to ignore for coverage. See [istanbul documentation](https://github.com/istanbuljs/nyc#ignoring-methods) for more information.


#### coverage.watermarks


* **Type:**



ts
```
{
  statements?: [number, number],
  functions?: [number, number],
  branches?: [number, number],
  lines?: [number, number]
}
```


```
{
  statements?: [number, number],
  functions?: [number, number],
  branches?: [number, number],
  lines?: [number, number]
}
```


* **Default:**



ts
```
{
  statements: [50, 80],
  functions: [50, 80],
  branches: [50, 80],
  lines: [50, 80]
}
```


```
{
  statements: [50, 80],
  functions: [50, 80],
  branches: [50, 80],
  lines: [50, 80]
}
```


* **Available for providers:** `'c8' | 'v8' | 'istanbul'`


Watermarks for statements, lines, branches and functions. See [istanbul documentation](https://github.com/istanbuljs/nyc#high-and-low-watermarks) for more information.


#### coverage.customProviderModule


* **Type:** `string`
* **Available for providers:** `'custom'`
* **CLI:** `--coverage.customProviderModule=<path or module name>`


Specifies the module name or path for the custom coverage provider module. See [Guide - Custom Coverage Provider](../guide/coverage#custom-coverage-provider) for more information.


### testNamePattern \*


* **Type** `string | RegExp`
* **CLI:** `-t <pattern>`, `--testNamePattern=<pattern>`, `--test-name-pattern=<pattern>`


Run tests with full names matching the pattern. If you add `OnlyRunThis` to this property, tests not containing the word `OnlyRunThis` in the test name will be skipped.



js
```
import { expect, test } from 'vitest'

// run
test('OnlyRunThis', () => {
  expect(true).toBe(true)
})

// skipped
test('doNotRun', () => {
  expect(true).toBe(true)
})
```


```
import { expect, test } from 'vitest'

// run
test('OnlyRunThis', () => {
  expect(true).toBe(true)
})

// skipped
test('doNotRun', () => {
  expect(true).toBe(true)
})
```


### open \*


* **Type:** `boolean`
* **Default:** `false`
* **CLI:** `--open`, `--open=false`


Open Vitest UI (WIP)


### api


* **Type:** `boolean | number`
* **Default:** `false`
* **CLI:** `--api`, `--api.port`, `--api.host`, `--api.strictPort`


Listen to port and serve API. When set to true, the default port is 51204


### browser


* **Type:** `{ enabled?, name?, provider?, headless?, api?, slowHijackESM? }`
* **Default:** `{ enabled: false, headless: process.env.CI, api: 63315 }`
* **Version:** Since Vitest 0.29.4
* **CLI:** `--browser`, `--browser=<name>`, `--browser.name=chrome --browser.headless`


Run Vitest tests in a browser. We use [WebdriverIO](https://webdriver.io/) for running tests by default, but it can be configured with [browser.provider](index#browser-provider) option.



**NOTE**Read more about testing in a real browser in the [guide page](../guide/browser).




**WARNING**This is an experimental feature. Breaking changes might not follow semver, please pin Vitest's version when using it.



#### browser.enabled


* **Type:** `boolean`
* **Default:** `false`
* **CLI:** `--browser`, `--browser.enabled=false`


Run all tests inside a browser by default. Can be overriden with [`poolMatchGlobs`](index#poolmatchglobs) option.


#### browser.name


* **Type:** `string`
* **CLI:** `--browser=safari`


Run all tests in a specific browser. Possible options in different providers:


* `webdriverio`: `firefox`, `chrome`, `edge`, `safari`
* `playwright`: `firefox`, `webkit`, `chromium`
* custom: any string that will be passed to the provider


#### browser.headless


* **Type:** `boolean`
* **Default:** `process.env.CI`
* **CLI:** `--browser.headless`, `--brower.headless=false`


Run the browser in a `headless` mode. If you are running Vitest in CI, it will be enabled by default.


#### browser.api


* **Type:** `number | { port?, strictPort?, host? }`
* **Default:** `63315`
* **CLI:** `--browser.api=63315`, `--browser.api.port=1234, --browser.api.host=example.com`


Configure options for Vite server that serves code in the browser. Does not affect [`test.api`](index#api) option.


#### browser.provider


* **Type:** `'webdriverio' | 'playwright' | string`
* **Default:** `'webdriverio'`
* **CLI:** `--browser.provider=playwright`


Path to a provider that will be used when running browser tests. Vitest provides two providers which are `webdriverio` (default) and `playwright`. Custom providers should be exported using `default` export and have this shape:



ts
```
export interface BrowserProvider {
  name: string
  getSupportedBrowsers(): readonly string[]
  initialize(ctx: Vitest, options: { browser: string }): Awaitable<void>
  openPage(url: string): Awaitable<void>
  close(): Awaitable<void>
}
```


```
export interface BrowserProvider {
  name: string
  getSupportedBrowsers(): readonly string[]
  initialize(ctx: Vitest, options: { browser: string }): Awaitable<void>
  openPage(url: string): Awaitable<void>
  close(): Awaitable<void>
}
```



**WARNING**This is an advanced API for library authors. If you just need to run tests in a browser, use the [browser](index#browser) option.



#### browser.slowHijackESM


* **Type:** `boolean`
* **Default:** `true`
* **Version:** Since Vitest 0.31.0


When running tests in Node.js Vitest can use its own module resolution to easily mock modules with `vi.mock` syntax. However it's not so easy to replicate ES module resolution in browser, so we need to transform your source files before browser can consume it.


This option has no effect on tests running inside Node.js.


This options is enabled by default when running in the browser. If you don't rely on spying on ES modules with `vi.spyOn` and don't use `vi.mock`, you can disable this to get a slight boost to performance.


### clearMocks


* **Type:** `boolean`
* **Default:** `false`


Will call [`.mockClear()`](../api/mock#mockclear) on all spies before each test. This will clear mock history, but not reset its implementation to the default one.


### mockReset


* **Type:** `boolean`
* **Default:** `false`


Will call [`.mockReset()`](../api/mock#mockreset) on all spies before each test. This will clear mock history and reset its implementation to an empty function (will return `undefined`).


### restoreMocks


* **Type:** `boolean`
* **Default:** `false`


Will call [`.mockRestore()`](../api/mock#mockrestore) on all spies before each test. This will clear mock history and reset its implementation to the original one.


### unstubEnvs


* **Type:** `boolean`
* **Default:** `false`
* **Version:** Since Vitest 0.26.0


Will call [`vi.unstubAllEnvs`](../api/vi#vi-unstuballenvs) before each test.


### unstubGlobals


* **Type:** `boolean`
* **Default:** `false`
* **Version:** Since Vitest 0.26.0


Will call [`vi.unstubAllGlobals`](../api/vi#vi-unstuballglobals) before each test.


### transformMode


* **Type:** `{ web?, ssr? }`


Determine the transform method of modules


#### transformMode.ssr


* **Type:** `RegExp[]`
* **Default:** `[/\.([cm]?[jt]sx?|json)$/]`


Use SSR transform pipeline for the specified files.  
 Vite plugins will receive `ssr: true` flag when processing those files.


#### transformMode.web


* **Type:** `RegExp[]`
* **Default:** *modules other than those specified in `transformMode.ssr`*


First do a normal transform pipeline (targeting browser), then do a SSR rewrite to run the code in Node.  
 Vite plugins will receive `ssr: false` flag when processing those files.


When you use JSX as component models other than React (e.g. Vue JSX or SolidJS), you might want to config as following to make `.tsx` / `.jsx` transformed as client-side components:



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    transformMode: {
      web: [/\.[jt]sx$/],
    },
  },
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    transformMode: {
      web: [/\.[jt]sx$/],
    },
  },
})
```


### snapshotFormat \*


* **Type:** `PrettyFormatOptions`


Format options for snapshot testing. These options are passed down to [`pretty-format`](https://www.npmjs.com/package/pretty-format).


### resolveSnapshotPath \*


* **Type**: `(testPath: string, snapExtension: string) => string`
* **Default**: stores snapshot files in `__snapshots__` directory


Overrides default snapshot path. For example, to store snapshots next to test files:



ts
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    resolveSnapshotPath: (testPath, snapExtension) => testPath + snapExtension,
  },
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    resolveSnapshotPath: (testPath, snapExtension) => testPath + snapExtension,
  },
})
```


### allowOnly


* **Type**: `boolean`
* **Default**: `false`
* **CLI:** `--allowOnly`, `--allowOnly=false`


Allow tests and suites that are marked as only.


### dangerouslyIgnoreUnhandledErrors \*


* **Type**: `boolean`
* **Default**: `false`
* **CLI:** `--dangerouslyIgnoreUnhandledErrors` `--dangerouslyIgnoreUnhandledErrors=false`


Ignore any unhandled errors that occur.


### passWithNoTests \*


* **Type**: `boolean`
* **Default**: `false`
* **CLI:** `--passWithNoTests`, `--passWithNoTests=false`


Vitest will not fail, if no tests will be found.


### logHeapUsage


* **Type**: `boolean`
* **Default**: `false`
* **CLI:** `--logHeapUsage`, `--logHeapUsage=false`


Show heap usage after each test. Useful for debugging memory leaks.


### css


* **Type**: `boolean | { include?, exclude?, modules? }`


Configure if CSS should be processed. When excluded, CSS files will be replaced with empty strings to bypass the subsequent processing. CSS Modules will return a proxy to not affect runtime.


#### css.include


* **Type**: `RegExp | RegExp[]`
* **Default**: `[]`


RegExp pattern for files that should return actual CSS and will be processed by Vite pipeline.



**TIP**To process all CSS files, use `/.+/`.



#### css.exclude


* **Type**: `RegExp | RegExp[]`
* **Default**: `[]`


RegExp pattern for files that will return an empty CSS file.


#### css.modules


* **Type**: `{ classNameStrategy? }`
* **Default**: `{}`


#### css.modules.classNameStrategy


* **Type**: `'stable' | 'scoped' | 'non-scoped'`
* **Default**: `'stable'`


If you decide to process CSS files, you can configure if class names inside CSS modules should be scoped. You can choose one of the options:


* `stable`: class names will be generated as `_${name}_${hashedFilename}`, which means that generated class will stay the same, if CSS content is changed, but will change, if the name of the file is modified, or file is moved to another folder. This setting is useful, if you use snapshot feature.
* `scoped`: class names will be generated as usual, respecting `css.modules.generateScopeName` method, if you have one and CSS processing is enabled. By default, filename will be generated as `_${name}_${hash}`, where hash includes filename and content of the file.
* `non-scoped`: class names will not be hashed.



**WARNING**By default, Vitest exports a proxy, bypassing CSS Modules processing. If you rely on CSS properties on your classes, you have to enable CSS processing using `include` option.



### maxConcurrency


* **Type**: `number`
* **Default**: `5`


A number of tests that are allowed to run at the same time marked with `test.concurrent`.


Test above this limit will be queued to run when available slot appears.


### cache \*


* **Type**: `false | { dir? }`


Options to configure Vitest cache policy. At the moment Vitest stores cache for test results to run the longer and failed tests first.


#### cache.dir


* **Type**: `string`
* **Default**: `node_modules/.vitest`


Path to cache directory.


### sequence


* **Type**: `{ sequencer?, shuffle?, seed?, hooks?, setupFiles? }`


Options for how tests should be sorted.


You can provide sequence options to CLI with dot notation:



sh
```
npx vitest --sequence.shuffle --sequence.seed=1000
```


```
npx vitest --sequence.shuffle --sequence.seed=1000
```


#### sequence.sequencer \*


* **Type**: `TestSequencerConstructor`
* **Default**: `BaseSequencer`


A custom class that defines methods for sharding and sorting. You can extend `BaseSequencer` from `vitest/node`, if you only need to redefine one of the `sort` and `shard` methods, but both should exist.


Sharding is happening before sorting, and only if `--shard` option is provided.


#### sequence.shuffle


* **Type**: `boolean`
* **Default**: `false`
* **CLI**: `--sequence.shuffle`, `--sequence.shuffle=false`


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


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


#### sequence.concurrent


* **Type**: `boolean`
* **Default**: `false`
* **CLI**: `--sequence.concurrent`, `--sequence.concurrent=false`
* **Version**: Since Vitest 0.32.2


If you want tests to run in parallel, you can enable it with this option, or CLI argument [`--sequence.concurrent`](../guide/cli).


#### sequence.seed \*


* **Type**: `number`
* **Default**: `Date.now()`
* **CLI**: `--sequence.seed=1000`


Sets the randomization seed, if tests are running in random order.


#### sequence.hooks


* **Type**: `'stack' | 'list' | 'parallel'`
* **Default**: `'parallel'`
* **CLI**: `--sequence.hooks=<value>`


Changes the order in which hooks are executed.


* `stack` will order "after" hooks in reverse order, "before" hooks will run in the order they were defined
* `list` will order all hooks in the order they are defined
* `parallel` will run hooks in a single group in parallel (hooks in parent suites will still run before the current suite's hooks)


#### sequence.setupFiles


* **Type**: `'list' | 'parallel'`
* **Default**: `'parallel'`
* **CLI**: `--sequence.setupFiles=<value>`
* **Version**: Since Vitest 0.29.3


Changes the order in which setup files are executed.


* `list` will run setup files in the order they are defined
* `parallel` will run setup files in parallel


### typecheck


Options for configuring [typechecking](../guide/testing-types) test environment.


#### typecheck.checker


* **Type**: `'tsc' | 'vue-tsc' | string`
* **Default**: `tsc`


What tools to use for type checking. Vitest will spawn a process with certain parameters for easier parsing, depending on the type. Checker should implement the same output format as `tsc`.


You need to have a package installed to use typechecker:


* `tsc` requires `typescript` package
* `vue-tsc` requires `vue-tsc` package


You can also pass down a path to custom binary or command name that produces the same output as `tsc --noEmit --pretty false`.


#### typecheck.include


* **Type**: `string[]`
* **Default**: `['**/?(*.){test,spec}-d.?(c|m)[jt]s?(x)']`


Glob pattern for files that should be treated as test files


#### typecheck.exclude


* **Type**: `string[]`
* **Default**: `['**/node_modules/**', '**/dist/**', '**/cypress/**', '**/.{idea,git,cache,output,temp}/**']`


Glob pattern for files that should not be treated as test files


#### typecheck.allowJs


* **Type**: `boolean`
* **Default**: `false`


Check JS files that have `@ts-check` comment. If you have it enabled in tsconfig, this will not overwrite it.


#### typecheck.ignoreSourceErrors


* **Type**: `boolean`
* **Default**: `false`


Do not fail, if Vitest found errors outside the test files. This will not show you non-test errors at all.


By default, if Vitest finds source error, it will fail test suite.


#### typecheck.tsconfig


* **Type**: `string`
* **Default**: *tries to find closest tsconfig.json*


Path to custom tsconfig, relative to the project root.


### slowTestThreshold \*


* **Type**: `number`
* **Default**: `300`


The number of milliseconds after which a test is considered slow and reported as such in the results.


### chaiConfig


* **Type:** `{ includeStack?, showDiff?, truncateThreshold? }`
* **Default:** `{ includeStack: false, showDiff: true, truncateThreshold: 40 }`
* **Version:** Since Vitest 0.30.0


Equivalent to [Chai config](https://github.com/chaijs/chai/blob/4.x.x/lib/chai/config.js).


#### chaiConfig.includeStack


* **Type:** `boolean`
* **Default:** `false`


Influences whether stack trace is included in Assertion error message. Default of false suppresses stack trace in the error message.


#### chaiConfig.showDiff


* **Type:** `boolean`
* **Default:** `true`


Influences whether or not the `showDiff` flag should be included in the thrown AssertionErrors. `false` will always be `false`; `true` will be true when the assertion has requested a diff to be shown.


#### chaiConfig.truncateThreshold


* **Type:** `number`
* **Default:** `40`


Sets length threshold for actual and expected values in assertion errors. If this threshold is exceeded, for example for large data structures, the value is replaced with something like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. Set it to `0` if you want to disable truncating altogether.


This config option affects truncating values in `test.each` titles and inside the assertion error message.


### bail


* **Type:** `number`
* **Default:** `0`
* **CLI**: `--bail=<value>`
* **Version:** Since Vitest 0.31.0


Stop test execution when given number of tests have failed.


By default Vitest will run all of your test cases even if some of them fail. This may not be desired for CI builds where you are only interested in 100% successful builds and would like to stop test execution as early as possible when test failures occur. The `bail` option can be used to speed up CI runs by preventing it from running more tests when failures have occured.


### retry


* **Type:** `number`
* **Default:** `0`
* **CLI:** `--retry=<value>`
* **Version:** Since Vitest 0.32.3


Retry the test specific number of times if it fails.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/config/>

Debugging
=========



**TIP**When debugging tests you might want to use `--test-timeout` CLI argument to prevent tests from timing out when stopping at breakpoints.



VSCode
------


Quick way to debug tests in VSCode is via `JavaScript Debug Terminal`. Open a new `JavaScript Debug Terminal` and run `npm run test` or `vitest` directly. *this works with any code ran in Node, so will work with most JS testing frameworks*


![image]


You can also add a dedicated launch configuration to debug a test file in VSCode:



json
```
{
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Current Test File",
      "autoAttachChildProcesses": true,
      "skipFiles": ["<node_internals>/**", "**/node_modules/**"],
      "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
      "args": ["run", "${relativeFile}"],
      "smartStep": true,
      "console": "integratedTerminal"
    }
  ]
}
```


```
{
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Current Test File",
      "autoAttachChildProcesses": true,
      "skipFiles": ["<node_internals>/**", "**/node_modules/**"],
      "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs",
      "args": ["run", "${relativeFile}"],
      "smartStep": true,
      "console": "integratedTerminal"
    }
  ]
}
```


Then in the debug tab, ensure 'Debug Current Test File' is selected. You can then open the test file you want to debug and press F5 to start debugging.


IntelliJ IDEA
-------------


Create a 'Node.js' run configuration. Use the following settings to run all tests in debug mode:




| Setting | Value |
| --- | --- |
| Working directory | /path/to/your-project-root |
| JavaScript file | ./node\_modules/vitest/vitest.mjs |
| Application parameters | run --threads false |


Then run this configuration in debug mode. The IDE will stop at JS/TS breakpoints set in the editor.


Node Inspector, e.g. Chrome DevTools
------------------------------------


Vitest also supports debugging tests without IDEs. However this requires that tests are not run parallel. Use one of the following commands to launch Vitest.



sh
```
# To run in a single worker
vitest --inspect-brk --single-thread

# To run in a child process
vitest --inspect-brk --no-threads
```


```
# To run in a single worker
vitest --inspect-brk --single-thread

# To run in a child process
vitest --inspect-brk --no-threads
```


Once Vitest starts it will stop execution and waits for you to open developer tools that can connect to [NodeJS inspector](https://nodejs.org/en/docs/guides/debugging-getting-started/). You can use Chrome DevTools for this by opening `chrome://inspect` on browser.


In watch mode you can keep the debugger open during test re-runs by using the `--single-thread --isolate false` options.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/debugging.html>

Comparisons with Other Test Runners
===================================


Jest
----


[Jest](https://jestjs.io/) took over the Testing Framework space by providing out-of-the-box support for most JavaScript projects, a comfortable API (`it` and `expect`), and the full pack of testing features that most setups would require (snapshots, mocks, coverage). We are thankful to the Jest team and community for creating a delightful testing API and pushing forward a lot of the testing patterns that are now a standard in the web ecosystem.


It is possible to use Jest in Vite setups. [@sodatea](https://twitter.com/haoqunjiang) built [vite-jest](https://github.com/sodatea/vite-jest#readme), which aims to provide first-class Vite integration for [Jest](https://jestjs.io/). The last [blockers in Jest](https://github.com/sodatea/vite-jest/blob/main/packages/vite-jest/README.md#vite-jest) have been solved, so this is a valid option for your unit tests.


However, in a world where we have [Vite](https://vitejs.dev) providing support for the most common web tooling (typescript, JSX, most popular UI Frameworks), Jest represents a duplication of complexity. If your app is powered by Vite, having two different pipelines to configure and maintain is not justifiable. With Vitest you get to define the configuration for your dev, build and test environments as a single pipeline, sharing the same plugins and the same vite.config.js.


Even if your library is not using Vite (for example, if it is built with esbuild or rollup), Vitest is an interesting option as it gives you a faster run for your unit tests and a jump in DX thanks to the default watch mode using Vite instant Hot Module Reload (HMR). Vitest offers compatibility with most of the Jest API and ecosystem libraries, so in most projects, it should be a drop-in replacement for Jest.


Cypress
-------


[Cypress](https://www.cypress.io/) is a browser-based test runner and a complementary tool to Vitest. If you'd like to use Cypress, we suggest using Vitest for all headless logic in your application and Cypress for all browser-based logic.


Cypress is known as an end-to-end testing tool, but their [new component test runner](https://on.cypress.io/component) has great support for testing Vite components and is an ideal choice to test anything that renders in a browser.


Browser-based runners, like Cypress, WebdriverIO and Web Test Runner, will catch issues that Vitest cannot because they use the real browser and real browser APIs.


Cypress's test driver is focused on determining if elements are visible, accessible, and interactive. Cypress is purpose-built for UI development and testing and its DX is centered around test driving your visual components. You see your component rendered alongside the test reporter. Once the test is complete, the component remains interactive and you can debug any failures that occur using your browser devtools.


In contrast, Vitest is focused on delivering the best DX possible for lightning fast, *headless* testing. Node-based runners like Vitest support various partially-implemented browser environments, like `jsdom`, which implement enough for you to quickly unit test any code that references browser APIs. The tradeoff is that these browser environments have limitations in what they can implement. For example, [jsdom is missing a number of features](https://github.com/jsdom/jsdom/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc) like `window.navigation` or a layout engine (`offsetTop`, etc).


Lastly, in contrast to the Web Test Runner, the Cypress test runner is more like an IDE than a test runner because you also see the real rendered component in the browser, along with its test results and logs.


Cypress has also been [integrating Vite in their products](https://www.youtube.com/watch?v=7S5cbY8iYLk): re-building their App's UI using [Vitesse](https://github.com/antfu/vitesse) and using Vite to test drive their project's development.


We believe that Cypress isn't a good option for unit testing headless code, but that using Cypress (for E2E and Component Testing) and Vitest (for unit tests) would cover your app's testing needs.


WebdriverIO
-----------


[WebdriverIO](https://webdriver.io/) is, similar to Cypress, a browser-based alternative test runner and a complementary tool to Vitest. It can be used as an end-to-end testing tool as well as for testing [web components](https://webdriver.io/docs/component-testing). It even uses components of Vitest under the hood, e.g. for [mocking and stubbing](https://webdriver.io/docs/mocksandspies/) within component tests.


WebdriverIO comes with the same advantages as Cypress allowing you to test your logic in real browser. However, it uses actual [web standards](https://w3c.github.io/webdriver/) for automation, which overcomes some of the tradeoffs and limitation when running tests in Cypress. Furthermore, it allows you to run tests on mobile as well, giving you access to test your application in even more environments.


Web Test Runner
---------------


[@web/test-runner](https://modern-web.dev/docs/test-runner/overview/) runs tests inside a headless browser, providing the same execution environment as your web application without the need for mocking out browser APIs or the DOM. This also makes it possible to debug inside a real browser using the devtools, although there is no UI shown for stepping through the test, as there is in Cypress tests. There is a watch mode, but it is not as intelligent as that of vitest, and may not always re-run the tests you want. To use @web/test-runner with a vite project, use [@remcovaes/web-test-runner-vite-plugin](https://github.com/remcovaes/web-test-runner-vite-plugin). @web/test-runner does not include assertion or mocking libraries, so it is up to you to add them.


uvu
---


[uvu](https://github.com/lukeed/uvu) is a test runner for Node.js and the browser. It runs tests in a single thread, so tests are not isolated and can leak across files. Vitest, however, uses worker threads to isolate tests and run them in parallel. For transforming your code, uvu relies on require and loader hooks. Vitest uses [Vite](https://vitejs.dev), so files are transformed with the full power of Vite's plugin system. In a world where we have Vite providing support for the most common web tooling (typescript, JSX, most popular UI Frameworks), uvu represents a duplication of complexity. If your app is powered by Vite, having two different pipelines to configure and maintain is not justifiable. With Vitest you get to define the configuration for your dev, build and test environments as a single pipeline, sharing the same plugins and the same vite.config.js. uvu does not provide an intelligent watch mode to rerun the changed tests, while Vitest gives you amazing DX thanks to the default watch mode using Vite instant Hot Module Reload (HMR). uvu is a fast option for running simple tests, but Vitest can be faster and more reliable for more complex tests and projects.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/comparisons.html>

Test Filtering
==============


Filtering, timeouts, concurrent for suite and tests


CLI
---


You can use CLI to filter test files by name:



bash
```
$ vitest basic
```


```
$ vitest basic
```


Will only execute test files that contain `basic`, e.g.




```
basic.test.ts
basic-foo.test.ts
basic/foo.test.ts
```


```
basic.test.ts
basic-foo.test.ts
basic/foo.test.ts
```


Specifying a Timeout
--------------------


You can optionally pass a timeout in milliseconds as third argument to tests. The default is 5 seconds.



ts
```
import { test } from 'vitest'

test('name', async () => { /* ... */ }, 1000)
```


```
import { test } from 'vitest'

test('name', async () => { /* ... */ }, 1000)
```


Hooks also can receive a timeout, with the same 5 seconds default.



ts
```
import { beforeAll } from 'vitest'

beforeAll(async () => { /* ... */ }, 1000)
```


```
import { beforeAll } from 'vitest'

beforeAll(async () => { /* ... */ }, 1000)
```


Skipping Suites and Tests
-------------------------


Use `.skip` to avoid running certain suites or tests



ts
```
import { assert, describe, it } from 'vitest'

describe.skip('skipped suite', () => {
  it('test', () => {
    // Suite skipped, no error
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('suite', () => {
  it.skip('skipped test', () => {
    // Test skipped, no error
    assert.equal(Math.sqrt(4), 3)
  })
})
```


```
import { assert, describe, it } from 'vitest'

describe.skip('skipped suite', () => {
  it('test', () => {
    // Suite skipped, no error
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('suite', () => {
  it.skip('skipped test', () => {
    // Test skipped, no error
    assert.equal(Math.sqrt(4), 3)
  })
})
```


Selecting Suites and Tests to Run
---------------------------------


Use `.only` to only run certain suites or tests



ts
```
import { assert, describe, it } from 'vitest'

// Only this suite (and others marked with only) are run
describe.only('suite', () => {
  it('test', () => {
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('another suite', () => {
  it('skipped test', () => {
    // Test skipped, as tests are running in Only mode
    assert.equal(Math.sqrt(4), 3)
  })

  it.only('test', () => {
    // Only this test (and others marked with only) are run
    assert.equal(Math.sqrt(4), 2)
  })
})
```


```
import { assert, describe, it } from 'vitest'

// Only this suite (and others marked with only) are run
describe.only('suite', () => {
  it('test', () => {
    assert.equal(Math.sqrt(4), 3)
  })
})

describe('another suite', () => {
  it('skipped test', () => {
    // Test skipped, as tests are running in Only mode
    assert.equal(Math.sqrt(4), 3)
  })

  it.only('test', () => {
    // Only this test (and others marked with only) are run
    assert.equal(Math.sqrt(4), 2)
  })
})
```


Unimplemented Suites and Tests
------------------------------


Use `.todo` to stub suites and tests that should be implemented



ts
```
import { describe, it } from 'vitest'

// An entry will be shown in the report for this suite
describe.todo('unimplemented suite')

// An entry will be shown in the report for this test
describe('suite', () => {
  it.todo('unimplemented test')
})
```


```
import { describe, it } from 'vitest'

// An entry will be shown in the report for this suite
describe.todo('unimplemented suite')

// An entry will be shown in the report for this test
describe('suite', () => {
  it.todo('unimplemented test')
})
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/filtering.html>

Coverage
========


Vitest supports Native code coverage via [`v8`](https://v8.dev/blog/javascript-code-coverage) and instrumented code coverage via [`istanbul`](https://istanbul.js.org/).



**INFO**The `c8` provider is being replaced by the [`v8`](https://v8.dev/blog/javascript-code-coverage) provider. It will be deprecated in the next major version.



Coverage Providers
------------------



**TIP**Since Vitest v0.22.0



Both `v8` and `istanbul` support are optional. By default, `v8` will be used.


You can select the coverage tool by setting `test.coverage.provider` to `v8` or `istanbul`:



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'istanbul' // or 'v8'
    },
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'istanbul' // or 'v8'
    },
  },
})
```


When you start the Vitest process, it will prompt you to install the corresponding support package automatically.


Or if you prefer to install them manually:



bash
```
# For v8
npm i -D @vitest/coverage-v8

# For istanbul
npm i -D @vitest/coverage-istanbul
```


```
# For v8
npm i -D @vitest/coverage-v8

# For istanbul
npm i -D @vitest/coverage-istanbul
```


Coverage Setup
--------------


To test with coverage enabled, you can pass the `--coverage` flag in CLI. By default, reporter `['text', 'html', 'clover', 'json']` will be used.



json
```
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}
```


```
{
  "scripts": {
    "test": "vitest",
    "coverage": "vitest run --coverage"
  }
}
```


To configure it, set `test.coverage` options in your config file:



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      reporter: ['text', 'json', 'html'],
    },
  },
})
```


Custom Coverage Provider
------------------------


It's also possible to provide your custom coverage provider by passing `'custom'` in `test.coverage.provider`:



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'custom',
      customProviderModule: 'my-custom-coverage-provider'
    },
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    coverage: {
      provider: 'custom',
      customProviderModule: 'my-custom-coverage-provider'
    },
  },
})
```


The custom providers require a `customProviderModule` option which is a module name or path where to load the `CoverageProviderModule` from. It must export an object that implements `CoverageProviderModule` as default export:



ts
```
// my-custom-coverage-provider.ts
import type { CoverageProvider, CoverageProviderModule, ResolvedCoverageOptions, Vitest } from 'vitest'

const CustomCoverageProviderModule: CoverageProviderModule = {
  getProvider(): CoverageProvider {
    return new CustomCoverageProvider()
  },

  // Implements rest of the CoverageProviderModule ...
}

class CustomCoverageProvider implements CoverageProvider {
  name = 'custom-coverage-provider'
  options!: ResolvedCoverageOptions

  initialize(ctx: Vitest) {
    this.options = ctx.config.coverage
  }

  // Implements rest of the CoverageProvider ...
}

export default CustomCoverageProviderModule
```


```
// my-custom-coverage-provider.ts
import type { CoverageProvider, CoverageProviderModule, ResolvedCoverageOptions, Vitest } from 'vitest'

const CustomCoverageProviderModule: CoverageProviderModule = {
  getProvider(): CoverageProvider {
    return new CustomCoverageProvider()
  },

  // Implements rest of the CoverageProviderModule ...
}

class CustomCoverageProvider implements CoverageProvider {
  name = 'custom-coverage-provider'
  options!: ResolvedCoverageOptions

  initialize(ctx: Vitest) {
    this.options = ctx.config.coverage
  }

  // Implements rest of the CoverageProvider ...
}

export default CustomCoverageProviderModule
```


Please refer to the type definition for more details.


Changing the default coverage folder location
---------------------------------------------


When running a coverage report, a `coverage` folder is created in the root directory of your project. If you want to move it to a different directory, use the `test.coverage.reportsDirectory` property in the `vite.config.js` file.



js
```
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    coverage: {
      reportsDirectory: './tests/unit/coverage'
    }
  }
})
```


```
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    coverage: {
      reportsDirectory: './tests/unit/coverage'
    }
  }
})
```


Ignoring code
-------------


Both coverage providers have their own ways how to ignore code from coverage reports:


* [`v8`](https://github.com/istanbuljs/v8-to-istanbul#ignoring-uncovered-lines)
* [`ìstanbul`](https://github.com/istanbuljs/nyc#parsing-hints-ignoring-lines)


When using TypeScript the source codes are transpiled using `esbuild`, which strips all comments from the source codes ([esbuild#516](https://github.com/evanw/esbuild/issues/516)). Comments which are considered as [legal comments](https://esbuild.github.io/api/#legal-comments) are preserved.


For `istanbul` provider you can include a `@preserve` keyword in the ignore hint. Beware that these ignore hints may now be included in final production build as well.



diff
```
-/* istanbul ignore if */
+/* istanbul ignore if -- @preserve */
if (condition) {
```


```
-/* istanbul ignore if */
+/* istanbul ignore if -- @preserve */
if (condition) {
```


For `v8` this does not cause any issues. You can use `c8 ignore` comments with Typescript as usual:



ts
```
/* c8 ignore next 3 */
if (condition) {
```


```
/* c8 ignore next 3 */
if (condition) {
```


Other Options
-------------


To see all configurable options for coverage, see the [coverage Config Reference](../config/index#coverage).


Vitest UI
---------


Since Vitest 0.31.0, you can check your coverage report in [Vitest UI](ui).


If you have configured coverage reporters, don't forget to add `html` reporter to the list, Vitest UI will only enable html coverage report if it is present.


![html coverage activation in Vitest UI]

 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/coverage.html>

Snapshot
========


[Learn Snapshot by video from Vue School](https://vueschool.io/lessons/snapshots-in-vitest?friend=vueuse)Snapshot tests are a very useful tool whenever you want to make sure the output of your functions does not change unexpectedly.


When using snapshot, Vitest will take a snapshot of the given value, then compares it to a reference snapshot file stored alongside the test. The test will fail if the two snapshots do not match: either the change is unexpected, or the reference snapshot needs to be updated to the new version of the result.


Use Snapshots
-------------


To snapshot a value, you can use the [`toMatchSnapshot()`](../api/expect#tomatchsnapshot) from `expect()` API:



ts
```
import { expect, it } from 'vitest'

it('toUpperCase', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchSnapshot()
})
```


```
import { expect, it } from 'vitest'

it('toUpperCase', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchSnapshot()
})
```


The first time this test is run, Vitest creates a snapshot file that looks like this:



js
```
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports['toUpperCase 1'] = '"FOOBAR"'
```


```
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports['toUpperCase 1'] = '"FOOBAR"'
```


The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process. On subsequent test runs, Vitest will compare the rendered output with the previous snapshot. If they match, the test will pass. If they don't match, either the test runner found a bug in your code that should be fixed, or the implementation has changed and the snapshot needs to be updated.



**WARNING**When using Snapshots with async concurrent tests, `expect` from the local [Test Context](test-context) must be used to ensure the right test is detected.



Inline Snapshots
----------------


Similarly, you can use the [`toMatchInlineSnapshot()`](../api/expect#tomatchinlinesnapshot) to store the snapshot inline within the test file.



ts
```
import { expect, it } from 'vitest'

it('toUpperCase', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchInlineSnapshot()
})
```


```
import { expect, it } from 'vitest'

it('toUpperCase', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchInlineSnapshot()
})
```


Instead of creating a snapshot file, Vitest will modify the test file directly to update the snapshot as a string:



ts
```
import { expect, it } from 'vitest'

it('toUpperCase', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchInlineSnapshot('"FOOBAR"')
})
```


```
import { expect, it } from 'vitest'

it('toUpperCase', () => {
  const result = toUpperCase('foobar')
  expect(result).toMatchInlineSnapshot('"FOOBAR"')
})
```


This allows you to see the expected output directly without jumping across different files.



**WARNING**When using Snapshots with async concurrent tests, `expect` from the local [Test Context](test-context) must be used to ensure the right test is detected.



Updating Snapshots
------------------


When the received value doesn't match the snapshot, the test fails and shows you the difference between them. When the snapshot change is expected, you may want to update the snapshot from the current state.


In watch mode, you can press the `u` key in the terminal to update the failed snapshot directly.


Or you can use the `--update` or `-u` flag in the CLI to make Vitest update snapshots.



bash
```
vitest -u
```


```
vitest -u
```


File Snapshots
--------------


When calling `toMatchSnapshot()`, we store all snapshots in a formatted snap file. That means we need to escaping some characters (namely the double-quote `"` and backtick ```) in the snapshot string. Meanwhile, you might lose the syntax highlighting for the snapshot content (if they are in some language).


To improve this case, we introduce [`toMatchFileSnapshot()`](../api/expect#tomatchfilesnapshot) to explicitly snapshot in a file. This allows you to assign any file extension to the snapshot file, and making them more readable.



ts
```
import { expect, it } from 'vitest'

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }))
  await expect(result).toMatchFileSnapshot('./test/basic.output.html')
})
```


```
import { expect, it } from 'vitest'

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }))
  await expect(result).toMatchFileSnapshot('./test/basic.output.html')
})
```


It will compare with the content of `./test/basic.output.html`. And can be written back with the `--update` flag.


Image Snapshots
---------------


It's also possible to snapshot images using [`jest-image-snapshot`](https://github.com/americanexpress/jest-image-snapshot).



bash
```
npm i -D jest-image-snapshot
```


```
npm i -D jest-image-snapshot
```



ts
```
test('image snapshot', () => {
  expect(readFileSync('./test/stubs/input-image.png'))
    .toMatchImageSnapshot()
})
```


```
test('image snapshot', () => {
  expect(readFileSync('./test/stubs/input-image.png'))
    .toMatchImageSnapshot()
})
```


You can learn more in the [`examples/image-snapshot`](https://github.com/vitest-dev/vitest/blob/main/examples/image-snapshot) example.


Custom Serializer
-----------------


You can add your own logic to alter how your snapshots are serialized. Like Jest, Vitest has default serializers for built-in JavaScript types, HTML elements, ImmutableJS and for React elements.


Example serializer module:



ts
```
expect.addSnapshotSerializer({
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer` is a function that serializes a value using existing plugins.
    return `Pretty foo: ${printer(val.foo)}`
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo')
  },
})
```


```
expect.addSnapshotSerializer({
  serialize(val, config, indentation, depth, refs, printer) {
    // `printer` is a function that serializes a value using existing plugins.
    return `Pretty foo: ${printer(val.foo)}`
  },
  test(val) {
    return val && Object.prototype.hasOwnProperty.call(val, 'foo')
  },
})
```


After adding a test like this:



ts
```
test('foo snapshot test', () => {
  const bar = {
    foo: {
      x: 1,
      y: 2,
    },
  }

  expect(bar).toMatchSnapshot()
})
```


```
test('foo snapshot test', () => {
  const bar = {
    foo: {
      x: 1,
      y: 2,
    },
  }

  expect(bar).toMatchSnapshot()
})
```


You will get the following snapshot:




```
Pretty foo: Object {
  "x": 1,
  "y": 2,
}
```


```
Pretty foo: Object {
  "x": 1,
  "y": 2,
}
```


We are using Jest's `pretty-format` for serializing snapshots. You can read more about it here: [pretty-format](https://github.com/facebook/jest/blob/main/packages/pretty-format/README.md#serialize).


Difference from Jest
--------------------


Vitest provides an almost compatible Snapshot feature with [Jest's](https://jestjs.io/docs/snapshot-testing) with a few exceptions:


#### 1. Comment header in the snapshot file is different



diff
```
- // Jest Snapshot v1, https://goo.gl/fbAQLP
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
```


```
- // Jest Snapshot v1, https://goo.gl/fbAQLP
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
```


This does not really affect the functionality but might affect your commit diff when migrating from Jest.


#### 2. `printBasicPrototype` is default to `false`


Both Jest and Vitest's snapshots are powered by [`pretty-format`](https://github.com/facebook/jest/blob/main/packages/pretty-format). In Vitest we set `printBasicPrototype` default to `false` to provide a cleaner snapshot output, while in Jest <29.0.0 it's `true` by default.



ts
```
import { expect, test } from 'vitest'

test('snapshot', () => {
  const bar = [
    {
      foo: 'bar',
    },
  ]

  // in Jest
  expect(bar).toMatchInlineSnapshot(`
    Array [
      Object {
        "foo": "bar",
      },
    ]
  `)

  // in Vitest
  expect(bar).toMatchInlineSnapshot(`
    [
      {
        "foo": "bar",
      },
    ]
  `)
})
```


```
import { expect, test } from 'vitest'

test('snapshot', () => {
  const bar = [
    {
      foo: 'bar',
    },
  ]

  // in Jest
  expect(bar).toMatchInlineSnapshot(`
    Array [
      Object {
        "foo": "bar",
      },
    ]
  `)

  // in Vitest
  expect(bar).toMatchInlineSnapshot(`
    [
      {
        "foo": "bar",
      },
    ]
  `)
})
```


We believe this is a more reasonable default for readability and overall DX. If you still prefer Jest's behavior, you can change your config:



ts
```
// vitest.config.js
export default defineConfig({
  test: {
    snapshotFormat: {
      printBasicPrototype: true
    }
  }
})
```


```
// vitest.config.js
export default defineConfig({
  test: {
    snapshotFormat: {
      printBasicPrototype: true
    }
  }
})
```


#### 3. Chevron `>` is used as a separator instead of colon `:` for custom messages


Vitest uses chevron `>` as a separator instead of colon `:` for readability, when a custom message is passed during creation of a snapshot file.


For the following example test code:



js
```
test('toThrowErrorMatchingSnapshot', () => {
  expect(() => {
    throw new Error('error')
  }).toThrowErrorMatchingSnapshot('hint')
})
```


```
test('toThrowErrorMatchingSnapshot', () => {
  expect(() => {
    throw new Error('error')
  }).toThrowErrorMatchingSnapshot('hint')
})
```


In Jest, the snapshot will be:



console
```
exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;
```


```
exports[`toThrowErrorMatchingSnapshot: hint 1`] = `"error"`;
```


In Vitest, the equivalent snapshot will be:



console
```
exports[`toThrowErrorMatchingSnapshot > hint 1`] = `"error"`;
```


```
exports[`toThrowErrorMatchingSnapshot > hint 1`] = `"error"`;
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/snapshot>

Mocking
=======


When writing tests it's only a matter of time before you need to create a "fake" version of an internal — or external — service. This is commonly referred to as **mocking**. Vitest provides utility functions to help you out through its **vi** helper. You can `import { vi } from 'vitest'` or access it **globally** (when [global configuration](../config/index#globals) is **enabled**).



**WARNING**Always remember to clear or restore mocks before or after each test run to undo mock state changes between runs! See [`mockReset`](../api/mock#mockreset) docs for more info.



If you wanna dive in head first, check out the [API section](../api/vi) otherwise keep reading to take a deeper dive into the world of mocking.


Dates
-----


Sometimes you need to be in control of the date to ensure consistency when testing. Vitest uses [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers) package for manipulating timers, as well as system date. You can find more about the specific API in detail [here](../api/vi#vi-setsystemtime).


### Example



js
```
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

const businessHours = [9, 17]

function purchase() {
  const currentHour = new Date().getHours()
  const [open, close] = businessHours

  if (currentHour > open && currentHour < close)
    return { message: 'Success' }

  return { message: 'Error' }
}

describe('purchasing flow', () => {
  beforeEach(() => {
    // tell vitest we use mocked time
    vi.useFakeTimers()
  })

  afterEach(() => {
    // restoring date after each test run
    vi.useRealTimers()
  })

  it('allows purchases within business hours', () => {
    // set hour within business hours
    const date = new Date(2000, 1, 1, 13)
    vi.setSystemTime(date)

    // access Date.now() will result in the date set above
    expect(purchase()).toEqual({ message: 'Success' })
  })

  it('disallows purchases outside of business hours', () => {
    // set hour outside business hours
    const date = new Date(2000, 1, 1, 19)
    vi.setSystemTime(date)

    // access Date.now() will result in the date set above
    expect(purchase()).toEqual({ message: 'Error' })
  })
})
```


```
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

const businessHours = [9, 17]

function purchase() {
  const currentHour = new Date().getHours()
  const [open, close] = businessHours

  if (currentHour > open && currentHour < close)
    return { message: 'Success' }

  return { message: 'Error' }
}

describe('purchasing flow', () => {
  beforeEach(() => {
    // tell vitest we use mocked time
    vi.useFakeTimers()
  })

  afterEach(() => {
    // restoring date after each test run
    vi.useRealTimers()
  })

  it('allows purchases within business hours', () => {
    // set hour within business hours
    const date = new Date(2000, 1, 1, 13)
    vi.setSystemTime(date)

    // access Date.now() will result in the date set above
    expect(purchase()).toEqual({ message: 'Success' })
  })

  it('disallows purchases outside of business hours', () => {
    // set hour outside business hours
    const date = new Date(2000, 1, 1, 19)
    vi.setSystemTime(date)

    // access Date.now() will result in the date set above
    expect(purchase()).toEqual({ message: 'Error' })
  })
})
```


Functions
---------


Mocking functions can be split up into two different categories; *spying & mocking*.


Sometimes all you need is to validate whether or not a specific function has been called (and possibly which arguments were passed). In these cases a spy would be all we need which you can use directly with `vi.spyOn()` ([read more here](../api/vi#vi-spyon)).


However spies can only help you **spy** on functions, they are not able to alter the implementation of those functions. In the case where we do need to create a fake (or mocked) version of a function we can use `vi.fn()` ([read more here](../api/vi#vi-fn)).


We use [Tinyspy](https://github.com/tinylibs/tinyspy) as a base for mocking functions, but we have our own wrapper to make it `jest` compatible. Both `vi.fn()` and `vi.spyOn()` share the same methods, however only the return result of `vi.fn()` is callable.


### Example



js
```
import { afterEach, describe, expect, it, vi } from 'vitest'

function getLatest(index = messages.items.length - 1) {
  return messages.items[index]
}

const messages = {
  items: [
    { message: 'Simple test message', from: 'Testman' },
    // ...
  ],
  getLatest, // can also be a `getter or setter if supported`
}

describe('reading messages', () => {
  afterEach(() => {
    vi.restoreAllMocks()
  })

  it('should get the latest message with a spy', () => {
    const spy = vi.spyOn(messages, 'getLatest')
    expect(spy.getMockName()).toEqual('getLatest')

    expect(messages.getLatest()).toEqual(
      messages.items[messages.items.length - 1],
    )

    expect(spy).toHaveBeenCalledTimes(1)

    spy.mockImplementationOnce(() => 'access-restricted')
    expect(messages.getLatest()).toEqual('access-restricted')

    expect(spy).toHaveBeenCalledTimes(2)
  })

  it('should get with a mock', () => {
    const mock = vi.fn().mockImplementation(getLatest)

    expect(mock()).toEqual(messages.items[messages.items.length - 1])
    expect(mock).toHaveBeenCalledTimes(1)

    mock.mockImplementationOnce(() => 'access-restricted')
    expect(mock()).toEqual('access-restricted')

    expect(mock).toHaveBeenCalledTimes(2)

    expect(mock()).toEqual(messages.items[messages.items.length - 1])
    expect(mock).toHaveBeenCalledTimes(3)
  })
})
```


```
import { afterEach, describe, expect, it, vi } from 'vitest'

function getLatest(index = messages.items.length - 1) {
  return messages.items[index]
}

const messages = {
  items: [
    { message: 'Simple test message', from: 'Testman' },
    // ...
  ],
  getLatest, // can also be a `getter or setter if supported`
}

describe('reading messages', () => {
  afterEach(() => {
    vi.restoreAllMocks()
  })

  it('should get the latest message with a spy', () => {
    const spy = vi.spyOn(messages, 'getLatest')
    expect(spy.getMockName()).toEqual('getLatest')

    expect(messages.getLatest()).toEqual(
      messages.items[messages.items.length - 1],
    )

    expect(spy).toHaveBeenCalledTimes(1)

    spy.mockImplementationOnce(() => 'access-restricted')
    expect(messages.getLatest()).toEqual('access-restricted')

    expect(spy).toHaveBeenCalledTimes(2)
  })

  it('should get with a mock', () => {
    const mock = vi.fn().mockImplementation(getLatest)

    expect(mock()).toEqual(messages.items[messages.items.length - 1])
    expect(mock).toHaveBeenCalledTimes(1)

    mock.mockImplementationOnce(() => 'access-restricted')
    expect(mock()).toEqual('access-restricted')

    expect(mock).toHaveBeenCalledTimes(2)

    expect(mock()).toEqual(messages.items[messages.items.length - 1])
    expect(mock).toHaveBeenCalledTimes(3)
  })
})
```


### More


* [Jest's Mock Functions](https://jestjs.io/docs/mock-function-api)


Globals
-------


You can mock global variables that are not present with `jsdom` or `node` by using [`vi.stubGlobal`](../api/vi#vi-stubglobal) helper. It will put the value of the global variable into a `globalThis` object.



ts
```
import { vi } from 'vitest'

const IntersectionObserverMock = vi.fn(() => ({
  disconnect: vi.fn(),
  observe: vi.fn(),
  takeRecords: vi.fn(),
  unobserve: vi.fn(),
}))

vi.stubGlobal('IntersectionObserver', IntersectionObserverMock)

// now you can access it as `IntersectionObserver` or `window.IntersectionObserver`
```


```
import { vi } from 'vitest'

const IntersectionObserverMock = vi.fn(() => ({
  disconnect: vi.fn(),
  observe: vi.fn(),
  takeRecords: vi.fn(),
  unobserve: vi.fn(),
}))

vi.stubGlobal('IntersectionObserver', IntersectionObserverMock)

// now you can access it as `IntersectionObserver` or `window.IntersectionObserver`
```


Modules
-------


Mock modules observe third-party-libraries, that are invoked in some other code, allowing you to test arguments, output or even redeclare its implementation.


See the [`vi.mock()` api section](../api/vi#vi-mock) for a more in-depth detailed API description.


### Automocking algorithm


If your code is importing a mocked module, without any associated `__mocks__` file or `factory` for this module, Vitest will mock the module itself by invoking it and mocking every export.


The following principles apply


* All arrays will be emptied
* All primitives and collections will stay the same
* All objects will be deeply cloned
* All instances of classes and their prototypes will be deeply cloned


### Example



js
```
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { Client } from 'pg'
import { failure, success } from './handlers.js'

// handlers
export function success(data) {}
export function failure(data) {}

// get todos
export async function getTodos(event, context) {
  const client = new Client({
    // ...clientOptions
  })

  await client.connect()

  try {
    const result = await client.query('SELECT * FROM todos;')

    client.end()

    return success({
      message: `${result.rowCount} item(s) returned`,
      data: result.rows,
      status: true,
    })
  }
  catch (e) {
    console.error(e.stack)

    client.end()

    return failure({ message: e, status: false })
  }
}

vi.mock('pg', () => {
  const Client = vi.fn()
  Client.prototype.connect = vi.fn()
  Client.prototype.query = vi.fn()
  Client.prototype.end = vi.fn()

  return { Client }
})

vi.mock('./handlers.js', () => {
  return {
    success: vi.fn(),
    failure: vi.fn(),
  }
})

describe('get a list of todo items', () => {
  let client

  beforeEach(() => {
    client = new Client()
  })

  afterEach(() => {
    vi.clearAllMocks()
  })

  it('should return items successfully', async () => {
    client.query.mockResolvedValueOnce({ rows: [], rowCount: 0 })

    await getTodos()

    expect(client.connect).toBeCalledTimes(1)
    expect(client.query).toBeCalledWith('SELECT * FROM todos;')
    expect(client.end).toBeCalledTimes(1)

    expect(success).toBeCalledWith({
      message: '0 item(s) returned',
      data: [],
      status: true,
    })
  })

  it('should throw an error', async () => {
    const mError = new Error('Unable to retrieve rows')
    client.query.mockRejectedValueOnce(mError)

    await getTodos()

    expect(client.connect).toBeCalledTimes(1)
    expect(client.query).toBeCalledWith('SELECT * FROM todos;')
    expect(client.end).toBeCalledTimes(1)
    expect(failure).toBeCalledWith({ message: mError, status: false })
  })
})
```


```
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { Client } from 'pg'
import { failure, success } from './handlers.js'

// handlers
export function success(data) {}
export function failure(data) {}

// get todos
export async function getTodos(event, context) {
  const client = new Client({
    // ...clientOptions
  })

  await client.connect()

  try {
    const result = await client.query('SELECT * FROM todos;')

    client.end()

    return success({
      message: `${result.rowCount} item(s) returned`,
      data: result.rows,
      status: true,
    })
  }
  catch (e) {
    console.error(e.stack)

    client.end()

    return failure({ message: e, status: false })
  }
}

vi.mock('pg', () => {
  const Client = vi.fn()
  Client.prototype.connect = vi.fn()
  Client.prototype.query = vi.fn()
  Client.prototype.end = vi.fn()

  return { Client }
})

vi.mock('./handlers.js', () => {
  return {
    success: vi.fn(),
    failure: vi.fn(),
  }
})

describe('get a list of todo items', () => {
  let client

  beforeEach(() => {
    client = new Client()
  })

  afterEach(() => {
    vi.clearAllMocks()
  })

  it('should return items successfully', async () => {
    client.query.mockResolvedValueOnce({ rows: [], rowCount: 0 })

    await getTodos()

    expect(client.connect).toBeCalledTimes(1)
    expect(client.query).toBeCalledWith('SELECT * FROM todos;')
    expect(client.end).toBeCalledTimes(1)

    expect(success).toBeCalledWith({
      message: '0 item(s) returned',
      data: [],
      status: true,
    })
  })

  it('should throw an error', async () => {
    const mError = new Error('Unable to retrieve rows')
    client.query.mockRejectedValueOnce(mError)

    await getTodos()

    expect(client.connect).toBeCalledTimes(1)
    expect(client.query).toBeCalledWith('SELECT * FROM todos;')
    expect(client.end).toBeCalledTimes(1)
    expect(failure).toBeCalledWith({ message: mError, status: false })
  })
})
```


Requests
--------


Because Vitest runs in Node, mocking network requests is tricky; web APIs are not available, so we need something that will mimic network behavior for us. We recommend [Mock Service Worker](https://mswjs.io/) to accomplish this. It will let you mock both `REST` and `GraphQL` network requests, and is framework agnostic.


Mock Service Worker (MSW) works by intercepting the requests your tests make, allowing you to use it without changing any of your application code. In-browser, this uses the [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API). In Node.js, and for Vitest, it uses [node-request-interceptor](https://mswjs.io/docs/api/setup-server#operation). To learn more about MSW, read their [introduction](https://mswjs.io/docs/)


### Configuration


You can use it like below in your [setup file](../config/index#setupfiles)



js
```
import { afterAll, afterEach, beforeAll } from 'vitest'
import { setupServer } from 'msw/node'
import { graphql, rest } from 'msw'

const posts = [
  {
    userId: 1,
    id: 1,
    title: 'first post title',
    body: 'first post body',
  },
  // ...
]

export const restHandlers = [
  rest.get('https://rest-endpoint.example/path/to/posts', (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(posts))
  }),
]

const graphqlHandlers = [
  graphql.query('https://graphql-endpoint.example/api/v1/posts', (req, res, ctx) => {
    return res(ctx.data(posts))
  }),
]

const server = setupServer(...restHandlers, ...graphqlHandlers)

// Start server before all tests
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

//  Close server after all tests
afterAll(() => server.close())

// Reset handlers after each test `important for test isolation`
afterEach(() => server.resetHandlers())
```


```
import { afterAll, afterEach, beforeAll } from 'vitest'
import { setupServer } from 'msw/node'
import { graphql, rest } from 'msw'

const posts = [
  {
    userId: 1,
    id: 1,
    title: 'first post title',
    body: 'first post body',
  },
  // ...
]

export const restHandlers = [
  rest.get('https://rest-endpoint.example/path/to/posts', (req, res, ctx) => {
    return res(ctx.status(200), ctx.json(posts))
  }),
]

const graphqlHandlers = [
  graphql.query('https://graphql-endpoint.example/api/v1/posts', (req, res, ctx) => {
    return res(ctx.data(posts))
  }),
]

const server = setupServer(...restHandlers, ...graphqlHandlers)

// Start server before all tests
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))

//  Close server after all tests
afterAll(() => server.close())

// Reset handlers after each test `important for test isolation`
afterEach(() => server.resetHandlers())
```



> Configuring the server with `onUnhandleRequest: 'error'` ensures that an error is thrown whenever there is a request that does not have a corresponding request handler.
> 
> 


### Example


We have a full working example which uses MSW: [React Testing with MSW](https://github.com/vitest-dev/vitest/tree/main/examples/react-testing-lib-msw).


### More


There is much more to MSW. You can access cookies and query parameters, define mock error responses, and much more! To see all you can do with MSW, read [their documentation](https://mswjs.io/docs/recipes).


Timers
------


When we test code that involves timeouts or intervals, instead of having our tests wait it out or timeout, we can speed up our tests by using "fake" timers that mock calls to `setTimeout` and `setInterval`.


See the [`vi.useFakeTimers` api section](../api/vi#vi-usefaketimers) for a more in depth detailed API description.


### Example



js
```
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

function executeAfterTwoHours(func) {
  setTimeout(func, 1000 * 60 * 60 * 2) // 2 hours
}

function executeEveryMinute(func) {
  setInterval(func, 1000 * 60) // 1 minute
}

const mock = vi.fn(() => console.log('executed'))

describe('delayed execution', () => {
  beforeEach(() => {
    vi.useFakeTimers()
  })
  afterEach(() => {
    vi.restoreAllMocks()
  })
  it('should execute the function', () => {
    executeAfterTwoHours(mock)
    vi.runAllTimers()
    expect(mock).toHaveBeenCalledTimes(1)
  })
  it('should not execute the function', () => {
    executeAfterTwoHours(mock)
    // advancing by 2ms won't trigger the func
    vi.advanceTimersByTime(2)
    expect(mock).not.toHaveBeenCalled()
  })
  it('should execute every minute', () => {
    executeEveryMinute(mock)
    vi.advanceTimersToNextTimer()
    expect(mock).toHaveBeenCalledTimes(1)
    vi.advanceTimersToNextTimer()
    expect(mock).toHaveBeenCalledTimes(2)
  })
})
```


```
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

function executeAfterTwoHours(func) {
  setTimeout(func, 1000 * 60 * 60 * 2) // 2 hours
}

function executeEveryMinute(func) {
  setInterval(func, 1000 * 60) // 1 minute
}

const mock = vi.fn(() => console.log('executed'))

describe('delayed execution', () => {
  beforeEach(() => {
    vi.useFakeTimers()
  })
  afterEach(() => {
    vi.restoreAllMocks()
  })
  it('should execute the function', () => {
    executeAfterTwoHours(mock)
    vi.runAllTimers()
    expect(mock).toHaveBeenCalledTimes(1)
  })
  it('should not execute the function', () => {
    executeAfterTwoHours(mock)
    // advancing by 2ms won't trigger the func
    vi.advanceTimersByTime(2)
    expect(mock).not.toHaveBeenCalled()
  })
  it('should execute every minute', () => {
    executeEveryMinute(mock)
    vi.advanceTimersToNextTimer()
    expect(mock).toHaveBeenCalledTimes(1)
    vi.advanceTimersToNextTimer()
    expect(mock).toHaveBeenCalledTimes(2)
  })
})
```


Cheat Sheet
-----------



**INFO**`vi` in the examples below is imported directly from `vitest`. You can also use it globally, if you set `globals` to `true` in your [config](../config/index).



I want to…


* Spy on a `method`



ts
```
const instance = new SomeClass()
vi.spyOn(instance, 'method')
```


```
const instance = new SomeClass()
vi.spyOn(instance, 'method')
```


* Mock exported variables



js
```
// some-path.js
export const getter = 'variable'
```


```
// some-path.js
export const getter = 'variable'
```



ts
```
// some-path.test.ts
import * as exports from './some-path.js'

vi.spyOn(exports, 'getter', 'get').mockReturnValue('mocked')
```


```
// some-path.test.ts
import * as exports from './some-path.js'

vi.spyOn(exports, 'getter', 'get').mockReturnValue('mocked')
```


* Mock exported function


Example with `vi.mock`:



ts
```
// ./some-path.js
export function method() {}
```


```
// ./some-path.js
export function method() {}
```



ts
```
import { method } from './some-path.js'

vi.mock('./some-path.js', () => ({
  method: vi.fn()
}))
```


```
import { method } from './some-path.js'

vi.mock('./some-path.js', () => ({
  method: vi.fn()
}))
```



**WARNING**Don't forget that `vi.mock` call is hoisted to top of the file. **Do not** put `vi.mock` calls inside `beforeEach`, only one of these will actually mock a module.



Example with `vi.spyOn`:



ts
```
import * as exports from './some-path.js'

vi.spyOn(exports, 'method').mockImplementation(() => {})
```


```
import * as exports from './some-path.js'

vi.spyOn(exports, 'method').mockImplementation(() => {})
```


* Mock exported class implementation


Example with `vi.mock` and prototype:



ts
```
// some-path.ts
export class SomeClass {}
```


```
// some-path.ts
export class SomeClass {}
```



ts
```
import { SomeClass } from './some-path.js'

vi.mock('./some-path.js', () => {
  const SomeClass = vi.fn()
  SomeClass.prototype.someMethod = vi.fn()
  return { SomeClass }
})
// SomeClass.mock.instances will have SomeClass
```


```
import { SomeClass } from './some-path.js'

vi.mock('./some-path.js', () => {
  const SomeClass = vi.fn()
  SomeClass.prototype.someMethod = vi.fn()
  return { SomeClass }
})
// SomeClass.mock.instances will have SomeClass
```


Example with `vi.mock` and return value:



ts
```
import { SomeClass } from './some-path.js'

vi.mock('./some-path.js', () => {
  const SomeClass = vi.fn(() => ({
    someMethod: vi.fn()
  }))
  return { SomeClass }
})
// SomeClass.mock.returns will have returned object
```


```
import { SomeClass } from './some-path.js'

vi.mock('./some-path.js', () => {
  const SomeClass = vi.fn(() => ({
    someMethod: vi.fn()
  }))
  return { SomeClass }
})
// SomeClass.mock.returns will have returned object
```


Example with `vi.spyOn`:



ts
```
import * as exports from './some-path.js'

vi.spyOn(exports, 'SomeClass').mockImplementation(() => {
  // whatever suites you from first two examples
})
```


```
import * as exports from './some-path.js'

vi.spyOn(exports, 'SomeClass').mockImplementation(() => {
  // whatever suites you from first two examples
})
```


* Spy on an object returned from a function


Example using cache:



ts
```
// some-path.ts
export function useObject() {
  return { method: () => true }
}
```


```
// some-path.ts
export function useObject() {
  return { method: () => true }
}
```



ts
```
// useObject.js
import { useObject } from './some-path.js'

const obj = useObject()
obj.method()
```


```
// useObject.js
import { useObject } from './some-path.js'

const obj = useObject()
obj.method()
```



ts
```
// useObject.test.js
import { useObject } from './some-path.js'

vi.mock('./some-path.js', () => {
  let _cache
  const useObject = () => {
    if (!_cache) {
      _cache = {
        method: vi.fn(),
      }
    }
    // now every time that useObject() is called it will
    // return the same object reference
    return _cache
  }
  return { useObject }
})

const obj = useObject()
// obj.method was called inside some-path
expect(obj.method).toHaveBeenCalled()
```


```
// useObject.test.js
import { useObject } from './some-path.js'

vi.mock('./some-path.js', () => {
  let _cache
  const useObject = () => {
    if (!_cache) {
      _cache = {
        method: vi.fn(),
      }
    }
    // now every time that useObject() is called it will
    // return the same object reference
    return _cache
  }
  return { useObject }
})

const obj = useObject()
// obj.method was called inside some-path
expect(obj.method).toHaveBeenCalled()
```


* Mock part of a module



ts
```
import { mocked, original } from './some-path.js'

vi.mock('./some-path.js', async () => {
  const mod = await vi.importActual<typeof import('./some-path.js')>('./some-path.js')
  return {
    ...mod,
    mocked: vi.fn()
  }
})
original() // has original behaviour
mocked() // is a spy function
```


```
import { mocked, original } from './some-path.js'

vi.mock('./some-path.js', async () => {
  const mod = await vi.importActual<typeof import('./some-path.js')>('./some-path.js')
  return {
    ...mod,
    mocked: vi.fn()
  }
})
original() // has original behaviour
mocked() // is a spy function
```


* Mock current date


To mock `Date`'s time, you can use `vi.setSystemTime` helper function. This value will **not** automatically reset between different tests.


Beware that using `vi.useFakeTimers` also changes the `Date`'s time.



ts
```
const mockDate = new Date(2022, 0, 1)
vi.setSystemTime(mockDate)
const now = new Date()
expect(now.valueOf()).toBe(mockDate.valueOf())
// reset mocked time
vi.useRealTimers()
```


```
const mockDate = new Date(2022, 0, 1)
vi.setSystemTime(mockDate)
const now = new Date()
expect(now.valueOf()).toBe(mockDate.valueOf())
// reset mocked time
vi.useRealTimers()
```


* Mock global variable


You can set global variable by assigning a value to `globalThis` or using [`vi.stubGlobal`](../api/vi#vi-stubglobal) helper. When using `vi.stubGlobal`, it will **not** automatically reset between different tests, unless you enable [`unstubGlobals`](../config/index#unstubglobals) config option or call [`vi.unstubAllGlobals`](../api/vi#vi-unstuballglobals).



ts
```
vi.stubGlobal('__VERSION__', '1.0.0')
expect(__VERSION__).toBe('1.0.0')
```


```
vi.stubGlobal('__VERSION__', '1.0.0')
expect(__VERSION__).toBe('1.0.0')
```


* Mock `import.meta.env`


To change environmental variable, you can just assign a new value to it. This value will **not** automatically reset between different tests.



ts
```
import { beforeEach, expect, it } from 'vitest'

// you can reset it in beforeEach hook manually
const originalViteEnv = import.meta.env.VITE_ENV

beforeEach(() => {
  import.meta.env.VITE_ENV = originalViteEnv
})

it('changes value', () => {
  import.meta.env.VITE_ENV = 'staging'
  expect(import.meta.env.VITE_ENV).toBe('staging')
})
```


```
import { beforeEach, expect, it } from 'vitest'

// you can reset it in beforeEach hook manually
const originalViteEnv = import.meta.env.VITE_ENV

beforeEach(() => {
  import.meta.env.VITE_ENV = originalViteEnv
})

it('changes value', () => {
  import.meta.env.VITE_ENV = 'staging'
  expect(import.meta.env.VITE_ENV).toBe('staging')
})
```


If you want to automatically reset value, you can use `vi.stubEnv` helper with [`unstubEnvs`](../config/index#unstubEnvs) config option enabled (or call [`vi.unstubAllEnvs`](../api/vi#vi-unstuballenvs) manually in `beforeEach` hook):



ts
```
import { expect, it, vi } from 'vitest'

// before running tests "VITE_ENV" is "test"
import.meta.env.VITE_ENV === 'test'

it('changes value', () => {
  vi.stubEnv('VITE_ENV', 'staging')
  expect(import.meta.env.VITE_ENV).toBe('staging')
})

it('the value is restored before running an other test', () => {
  expect(import.meta.env.VITE_ENV).toBe('test')
})
```


```
import { expect, it, vi } from 'vitest'

// before running tests "VITE_ENV" is "test"
import.meta.env.VITE_ENV === 'test'

it('changes value', () => {
  vi.stubEnv('VITE_ENV', 'staging')
  expect(import.meta.env.VITE_ENV).toBe('staging')
})

it('the value is restored before running an other test', () => {
  expect(import.meta.env.VITE_ENV).toBe('test')
})
```



ts
```
// vitest.config.ts
export default {
  test: {
    unstubAllEnvs: true,
  }
}
```


```
// vitest.config.ts
export default {
  test: {
    unstubAllEnvs: true,
  }
}
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/mocking.html>

Testing Types
=============


Vitest allows you to write tests for your types, using `expectTypeOf` or `assertType` syntaxes. By default all tests inside `*.test-d.ts` files are considered type tests, but you can change it with [`typecheck.include`](../config/index#typecheck-include) config option.


Under the hood Vitest calls `tsc` or `vue-tsc`, depending on your config, and parses results. Vitest will also print out type errors in your source code, if it finds any. You can disable it with [`typecheck.ignoreSourceErrors`](../config/index#typecheck-ignoresourceerrors) config option.


Keep in mind that Vitest doesn't run or compile these files, they are only statically analyzed by the compiler, and because of that you cannot use any dynamic statements. Meaning, you cannot use dynamic test names, and `test.each`, `test.runIf`, `test.skipIf`, `test.concurrent` APIs. But you can use other APIs, like `test`, `describe`, `.only`, `.skip` and `.todo`.


Using CLI flags, like `--allowOnly` and `-t` are also supported for type checking.



ts
```
import { assertType, expectTypeOf } from 'vitest'
import { mount } from './mount.js'

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction()
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>()

  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }))
})
```


```
import { assertType, expectTypeOf } from 'vitest'
import { mount } from './mount.js'

test('my types work properly', () => {
  expectTypeOf(mount).toBeFunction()
  expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>()

  // @ts-expect-error name is a string
  assertType(mount({ name: 42 }))
})
```


Any type error triggered inside a test file will be treated as a test error, so you can use any type trick you want to test types of your project.


You can see a list of possible matchers in [API section](../api/expect-typeof).


Reading Errors
--------------


If you are using `expectTypeOf` API, you might notice hard to read errors or unexpected:



ts
```
expectTypeOf(1).toEqualTypeOf<string>()
//             ^^^^^^^^^^^^^^^^^^^^^^
// index-c3943160.d.ts(90, 20): Arguments for the rest parameter 'MISMATCH' were not provided.
```


```
expectTypeOf(1).toEqualTypeOf<string>()
//             ^^^^^^^^^^^^^^^^^^^^^^
// index-c3943160.d.ts(90, 20): Arguments for the rest parameter 'MISMATCH' were not provided.
```


This is due to how [`expect-type`](https://github.com/mmkal/expect-type) handles type errors.


Unfortunately, TypeScript doesn't provide type metadata without patching, so we cannot provide useful error messages at this point, but there are [works in TypeScript project](https://github.com/microsoft/TypeScript/pull/40468) to fix this. If you want better messages, please, ask TypeScript team to have a look at mentioned PR.


If you find it hard working with `expectTypeOf` API and figuring out errors, you can always use more simple `assertType` API:



ts
```
const answer = 42

assertType<number>(answer)
// @ts-expect-error answer is not a string
assertType<string>(answer)
```


```
const answer = 42

assertType<number>(answer)
// @ts-expect-error answer is not a string
assertType<string>(answer)
```



**TIP**When using `@ts-expect-error` syntax, you might want to make sure that you didn't make a typo. You can do that by including your type files in [`test.include`](../config/index#include) config option, so Vitest will also actually *run* these tests and fail with `ReferenceError`.


This will pass, because it expects an error, but the word “answer” has a typo, so it's a false positive error:



ts
```
// @ts-expect-error answer is not a string
assertType<string>(answr) //
```


```
// @ts-expect-error answer is not a string
assertType<string>(answr) //
```



Run typechecking
----------------


Add this command to your `scripts` section in `package.json`:



json
```
{
  "scripts": {
    "typecheck": "vitest typecheck"
  }
}
```


```
{
  "scripts": {
    "typecheck": "vitest typecheck"
  }
}
```


Now you can run typecheck:



sh
```
# npm
npm run typecheck

# yarn
yarn typecheck

# pnpm
pnpm run typecheck
```


```
# npm
npm run typecheck

# yarn
yarn typecheck

# pnpm
pnpm run typecheck
```


Vitest uses `tsc --noEmit` or `vue-tsc --noEmit`, depending on your configuration, so you can remove these scripts from your pipeline.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/testing-types.html>

Vitest UI
=========


Powered by Vite, Vitest also has a dev server under the hood when running the tests. This allows Vitest to provide a beautiful UI to view and interact with your tests. The Vitest UI is optional, so you'll need to install it with:



bash
```
npm i -D @vitest/ui
```


```
npm i -D @vitest/ui
```


Then you can start the tests with UI by passing the `--ui` flag:



bash
```
vitest --ui
```


```
vitest --ui
```


Then you can visit the Vitest UI at [`http://localhost:51204/__vitest__/`](http://localhost:51204/__vitest__/)


![Vitest UI](https://user-images.githubusercontent.com/11247099/171992267-5cae2fa0-b927-400a-8eb1-da776974cb61.png)![Vitest UI](https://user-images.githubusercontent.com/11247099/171992272-7c6057e2-80c3-4b17-a7b6-0ac28e5a5e0b.png)Since Vitest 0.26.0, UI can also be used as a reporter. Use `'html'` reporter in your Vitest configuration to generate HTML output and preview the results of your tests:



ts
```
// vitest.config.ts

export default {
  test: {
    reporters: ['html']
  }
}
```


```
// vitest.config.ts

export default {
  test: {
    reporters: ['html']
  }
}
```


Since Vitest 0.31.0, you can check your coverage report in Vitest UI: check [Vitest UI Coverage](coverage#vitest-ui) for more details.



**WARNING**If you still want to see how your tests are running in real time in the terminal, don't forget to add `default` reporter to `reporters` option: `['default', 'html']`.




**TIP**To preview your HTML report, you can use [vite preview](https://vitejs.dev/guide/cli.html#vite-preview) command:



sh
```
npx vite preview --outDir ./html
```


```
npx vite preview --outDir ./html
```


You can configure output with [`outputFile`](../config/index#outputfile) config option. You need to specify `.html` path there. For example, `./html/index.html` is the default value.




 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/ui.html>

Browser Mode (experimental)
===========================


This page provides information about the experimental browser mode feature in the Vitest API, which allows you to run your tests in the browser natively, providing access to browser globals like window and document. This feature is currently under development, and APIs may change in the future.


Motivation
----------


We developed the Vitest browser mode feature to help improve testing workflows and achieve more accurate and reliable test results. This experimental addition to our testing API allows developers to run tests in a native browser environment. In this section, we'll explore the motivations behind this feature and its benefits for testing.


### Different ways of testing


There are different ways to test JavaScript code. Some testing frameworks simulate browser environments in Node.js, while others run tests in real browsers. In this context, [jsdom](https://www.npmjs.com/package/jsdom) is an example of a spec implementation that simulates a browser environment by being used with a test runner like Jest or Vitest, while other testing tools such as [WebdriverIO](https://webdriver.io/) or [Cypress](https://www.cypress.io/) allow developers to test their applications in a real browser or in case of [Playwright](https://playwright.dev/) provide you a browser engine.


### The simulation caveat


Testing JavaScript programs in simulated environments such as jsdom or happy-dom has simplified the test setup and provided an easy-to-use API, making them suitable for many projects and increasing confidence in test results. However, it is crucial to keep in mind that these tools only simulate a browser environment and not an actual browser, which may result in some discrepancies between the simulated environment and the real environment. Therefore, false positives or negatives in test results may occur.


To achieve the highest level of confidence in our tests, it's crucial to test in a real browser environment. This is why we developed the browser mode feature in Vitest, allowing developers to run tests natively in a browser and gain more accurate and reliable test results. With browser-level testing, developers can be more confident that their application will work as intended in a real-world scenario.


Drawbacks
---------


When using Vitest browser, it is important to consider the following drawbacks:


### Early Development


The browser mode feature of Vitest is still in its early stages of development. As such, it may not yet be fully optimized, and there may be some bugs or issues that have not yet been ironed out. It is recommended that users augment their Vitest browser experience with a standalone browser-side test runner like WebdriverIO, Cypress or Playwright.


### Longer Initialization


Vitest browser requires spinning up the provider and the browser during the initialization process, which can take some time. This can result in longer initialization times compared to other testing patterns.


Configuration
-------------


To activate browser mode in your Vitest configuration, you can use the `--browser` flag or set the `browser.enabled` field to `true` in your Vitest configuration file. Here is an example configuration using the browser field:



ts
```
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      name: 'chrome', // browser name is required
    },
  }
})
```


```
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      name: 'chrome', // browser name is required
    },
  }
})
```


Browser Option Types:
---------------------


The browser option in Vitest depends on the provider. Vitest will fail, if you pass `--browser` and don't specify its name in the config file. Available options:


* `webdriverio` (default) supports these browsers:
	+ `firefox`
	+ `chrome`
	+ `edge`
	+ `safari`
* `playwright` supports these browsers:
	+ `firefox`
	+ `webkit`
	+ `chromium`


Cross-browser Testing:
----------------------


When you specify a browser name in the browser option, Vitest will try to run the specified browser using [WebdriverIO](https://webdriver.io/) by default, and then run the tests there. This feature makes cross-browser testing easy to use and configure in environments like a CI. If you don't want to use WebdriverIO, you can configure the custom browser provider by using `browser.provider` option.


To specify a browser using the CLI, use the `--browser` flag followed by the browser name, like this:



sh
```
npx vitest --browser=chrome
```


```
npx vitest --browser=chrome
```


Or you can provide browser options to CLI with dot notation:



sh
```
npx vitest --browser.name=chrome --browser.headless
```


```
npx vitest --browser.name=chrome --browser.headless
```



**NOTE**When using the Safari browser option with WebdriverIO, the `safaridriver` needs to be activated by running `sudo safaridriver --enable` on your device.


Additionally, when running your tests, Vitest will attempt to install some drivers for compatibility with `safaridriver`.



Headless
--------


Headless mode is another option available in the browser mode. In headless mode, the browser runs in the background without a user interface, which makes it useful for running automated tests. The headless option in Vitest can be set to a boolean value to enable or disable headless mode.


Here's an example configuration enabling headless mode:



ts
```
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      headless: true,
    },
  }
})
```


```
export default defineConfig({
  test: {
    browser: {
      enabled: true,
      headless: true,
    },
  }
})
```


You can also set headless mode using the `--browser.headless` flag in the CLI, like this:



sh
```
npx vitest --browser.name=chrome --browser.headless
```


```
npx vitest --browser.name=chrome --browser.headless
```


In this case, Vitest will run in headless mode using the Chrome browser.


Limitations
-----------


### Thread Blocking Dialogs


When using Vitest Browser, it's important to note that thread blocking dialogs like `alert` or `confirm` cannot be used natively. This is because they block the web page, which means Vitest cannot continue communicating with the page, causing the execution to hang.


In such situations, Vitest provides default mocks with default returned values for these APIs. This ensures that if the user accidentally uses synchronous popup web APIs, the execution would not hang. However, it's still recommended for the user to mock these web APIs for better experience. Read more in [Mocking](mocking).



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/browser.html>

In-source testing
=================


Vitest also provides a way to run tests within your source code along side the implementation, similar to [Rust's module tests](https://doc.rust-lang.org/book/ch11-03-test-organization.html#the-tests-module-and-cfgtest).


This makes the tests share the same closure as the implementations and able to test against private states without exporting. Meanwhile, it also brings a closer feedback loop for development.


Setup
-----


To get started, put a `if (import.meta.vitest)` block at the end of your source file and write some tests inside it. For example:



ts
```
// src/index.ts

// the implementation
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}
```


```
// src/index.ts

// the implementation
export function add(...args: number[]) {
  return args.reduce((a, b) => a + b, 0)
}

// in-source test suites
if (import.meta.vitest) {
  const { it, expect } = import.meta.vitest
  it('add', () => {
    expect(add()).toBe(0)
    expect(add(1)).toBe(1)
    expect(add(1, 2, 3)).toBe(6)
  })
}
```


Update the `includeSource` config for Vitest to grab the files under `src/`:



ts
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    includeSource: ['src/**/*.{js,ts}'],
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    includeSource: ['src/**/*.{js,ts}'],
  },
})
```


Then you can start to test!



bash
```
$ npx vitest
```


```
$ npx vitest
```


Production build
----------------


For the production build, you will need to set the `define` options in your config file, letting the bundler do the dead code elimination. For example, in Vite



diff
```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
+ define: {
+   'import.meta.vitest': 'undefined',
+ },
  test: {
    includeSource: ['src/**/*.{js,ts}']
  },
})
```


```
// vite.config.ts
import { defineConfig } from 'vitest/config'

export default defineConfig({
+ define: {
+   'import.meta.vitest': 'undefined',
+ },
  test: {
    includeSource: ['src/**/*.{js,ts}']
  },
})
```


### Other Bundlers



unbuild
diff
```
// build.config.ts
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
+ replace: {
+   'import.meta.vitest': 'undefined',
+ },
  // other options
})
```


```
// build.config.ts
import { defineBuildConfig } from 'unbuild'

export default defineBuildConfig({
+ replace: {
+   'import.meta.vitest': 'undefined',
+ },
  // other options
})
```


Learn more: [unbuild](https://github.com/unjs/unbuild)




rollup
diff
```
// rollup.config.js
+ import replace from '@rollup/plugin-replace'

export default {
  plugins: [
+   replace({
+     'import.meta.vitest': 'undefined',
+   })
  ],
  // other options
}
```


```
// rollup.config.js
+ import replace from '@rollup/plugin-replace'

export default {
  plugins: [
+   replace({
+     'import.meta.vitest': 'undefined',
+   })
  ],
  // other options
}
```


Learn more: [rollup](https://rollupjs.org/)



TypeScript
----------


To get TypeScript support for `import.meta.vitest`, add `vitest/importMeta` to your `tsconfig.json`:



diff
```
// tsconfig.json
{
  "compilerOptions": {
    "types": [
+     "vitest/importMeta"
    ]
  }
}
```


```
// tsconfig.json
{
  "compilerOptions": {
    "types": [
+     "vitest/importMeta"
    ]
  }
}
```


Reference to [`test/import-meta`](https://github.com/vitest-dev/vitest/tree/main/test/import-meta) for the full example.


Notes
-----


This feature could be useful for:


* Unit testing for small-scoped functions or utilities
* Prototyping
* Inline Assertion


It's recommended to **use separate test files instead** for more complex tests like components or E2E testing.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/in-source>

Test Context
============


Inspired by [Playwright Fixtures](https://playwright.dev/docs/test-fixtures), Vitest's test context allows you to define utils, states, and fixtures that can be used in your tests.


Usage
-----


The first argument for each test callback is a test context.



ts
```
import { it } from 'vitest'

it('should work', (ctx) => {
  // prints name of the test
  console.log(ctx.task.name)
})
```


```
import { it } from 'vitest'

it('should work', (ctx) => {
  // prints name of the test
  console.log(ctx.task.name)
})
```


Built-in Test Context
---------------------


#### 
`context.task`


A readonly object containing metadata about the test.


#### 
`context.expect`


The `expect` API bound to the current test.


Extend Test Context
-------------------


Vitest provides two diffident ways to help you extend the test context.


### 
`test.extend`



**WARNING**This API is available since Vitest 0.32.3.



Like [Playwright](https://playwright.dev/docs/api/class-test#test-extend), you can use this method to define your own `test` API with custom fixtures and reuse it anywhere.


For example, we first create `myTest` with two fixtures, `todos` and `archive`.



ts
```
// my-test.ts
import { test } from 'vitest'

const todos = []
const archive = []

export const myTest = test.extend({
  todos: async ({ task }, use) => {
    // setup the fixture before each test function
    todos.push(1, 2, 3)

    // use the fixture value
    await use(todos)

    // cleanup the fixture after each test function
    todos.length = 0
  },
  archive
})
```


```
// my-test.ts
import { test } from 'vitest'

const todos = []
const archive = []

export const myTest = test.extend({
  todos: async ({ task }, use) => {
    // setup the fixture before each test function
    todos.push(1, 2, 3)

    // use the fixture value
    await use(todos)

    // cleanup the fixture after each test function
    todos.length = 0
  },
  archive
})
```


Then we can import and use it.



ts
```
import { expect } from 'vitest'
import { myTest } from './my-test.ts'

myTest('add items to todos', ({ todos }) => {
  expect(todos.length).toBe(3)

  todos.add(4)
  expect(todos.length).toBe(4)
})

myTest('move items from todos to archive', ({ todos, archive }) => {
  expect(todos.length).toBe(3)
  expect(archive.length).toBe(0)

  archive.push(todos.pop())
  expect(todos.length).toBe(2)
  expect(archive.length).toBe(1)
})
```


```
import { expect } from 'vitest'
import { myTest } from './my-test.ts'

myTest('add items to todos', ({ todos }) => {
  expect(todos.length).toBe(3)

  todos.add(4)
  expect(todos.length).toBe(4)
})

myTest('move items from todos to archive', ({ todos, archive }) => {
  expect(todos.length).toBe(3)
  expect(archive.length).toBe(0)

  archive.push(todos.pop())
  expect(todos.length).toBe(2)
  expect(archive.length).toBe(1)
})
```


We can also add more fixtures or override existing fixtures by extending `myTest`.



ts
```
export const myTest2 = myTest.extend({
  settings: {
    // ...
  }
})
```


```
export const myTest2 = myTest.extend({
  settings: {
    // ...
  }
})
```


#### Fixture initialization


Vitest runner will smartly initialize your fixtures and inject them into the test context based on usage.



ts
```
import { test } from 'vitest'

async function todosFn({ task }, use) {
  await use([1, 2, 3])
}

const myTest = test.extend({
  todos: todosFn,
  archive: []
})

// todosFn will not run
myTest('', () => {})
myTets('', ({ archive }) => {})

// todosFn will run
myTest('', ({ todos }) => {})
```


```
import { test } from 'vitest'

async function todosFn({ task }, use) {
  await use([1, 2, 3])
}

const myTest = test.extend({
  todos: todosFn,
  archive: []
})

// todosFn will not run
myTest('', () => {})
myTets('', ({ archive }) => {})

// todosFn will run
myTest('', ({ todos }) => {})
```



**WARNING**When using `test.extend()` with fixtures, you should always use the object destructuring pattern `{ todos }` to access context both in fixture function and test function.



#### TypeScript


To provide fixture types for all your custom contexts, you can pass the fixtures type as a generic.



ts
```
interface MyFixtures {
  todos: number[]
  archive: number[]
}

const myTest = test.extend<MyFixtures>({
  todos: [],
  archive: []
})

myTest('', (context) => {
  expectTypeOf(context.todos).toEqualTypeOf<number[]>()
  expectTypeOf(context.archive).toEqualTypeOf<number[]>()
})
```


```
interface MyFixtures {
  todos: number[]
  archive: number[]
}

const myTest = test.extend<MyFixtures>({
  todos: [],
  archive: []
})

myTest('', (context) => {
  expectTypeOf(context.todos).toEqualTypeOf<number[]>()
  expectTypeOf(context.archive).toEqualTypeOf<number[]>()
})
```


### 
`beforeEach` and `afterEach`


The contexts are different for each test. You can access and extend them within the `beforeEach` and `afterEach` hooks.



ts
```
import { beforeEach, it } from 'vitest'

beforeEach(async (context) => {
  // extend context
  context.foo = 'bar'
})

it('should work', ({ foo }) => {
  console.log(foo) // 'bar'
})
```


```
import { beforeEach, it } from 'vitest'

beforeEach(async (context) => {
  // extend context
  context.foo = 'bar'
})

it('should work', ({ foo }) => {
  console.log(foo) // 'bar'
})
```


#### TypeScript


To provide property types for all your custom contexts, you can aggregate the `TestContext` type by adding



ts
```
declare module 'vitest' {
  export interface TestContext {
    foo?: string
  }
}
```


```
declare module 'vitest' {
  export interface TestContext {
    foo?: string
  }
}
```


If you want to provide property types only for specific `beforeEach`, `afterEach`, `it` and `test` hooks, you can pass the type as a generic.



ts
```
interface LocalTestContext {
  foo: string
}

beforeEach<LocalTestContext>(async (context) => {
  // typeof context is 'TestContext & LocalTestContext'
  context.foo = 'bar'
})

it<LocalTestContext>('should work', ({ foo }) => {
  // typeof foo is 'string'
  console.log(foo) // 'bar'
})
```


```
interface LocalTestContext {
  foo: string
}

beforeEach<LocalTestContext>(async (context) => {
  // typeof context is 'TestContext & LocalTestContext'
  context.foo = 'bar'
})

it<LocalTestContext>('should work', ({ foo }) => {
  // typeof foo is 'string'
  console.log(foo) // 'bar'
})
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/test-context.html>

Test Environment
================


Vitest provides [`environment`](../config/index#environment) option to run code inside a specific environment. You can modify how environment behaves with [`environmentOptions`](../config/index#environmentoptions) option.


By default, you can use these environments:


* `node` is default environment
* `jsdom` emulates browser environment by providing Browser API, uses [`jsdom`](https://github.com/jsdom/jsdom) package
* `happy-dom` emulates browser environment by providing Browser API, and considered to be faster than jsdom, but lacks some API, uses [`happy-dom`](https://github.com/capricorn86/happy-dom) package
* `edge-runtime` emulates Vercel's [edge-runtime](https://edge-runtime.vercel.app/), uses [`@edge-runtime/vm`](https://www.npmjs.com/package/@edge-runtime/vm) package


Environments for specific files
-------------------------------


When setting `environment` option in your config, it will apply to all the test files in your project. To have more fine-grained control, you can use control comments to specify environment for specific files. Control comments are comments that start with `@vitest-environment` and are followed by the environment name:



ts
```
// @vitest-environment jsdom

import { test } from 'vitest'

test('test', () => {
  expect(typeof window).not.toBe('undefined')
})
```


```
// @vitest-environment jsdom

import { test } from 'vitest'

test('test', () => {
  expect(typeof window).not.toBe('undefined')
})
```


Or you can also set [`environmentMatchGlobs`](../config/index#environmentmatchglobs) option specifying the environment based on the glob patterns.


Custom Environment
------------------


Starting from 0.23.0, you can create your own package to extend Vitest environment. To do so, create package with the name `vitest-environment-${name}`. That package should export an object with the shape of `Environment`:



ts
```
import type { Environment } from 'vitest'

export default <Environment>{
  name: 'custom',
  setup() {
    // custom setup
    return {
      teardown() {
        // called after all tests with this env have been run
      }
    }
  }
}
```


```
import type { Environment } from 'vitest'

export default <Environment>{
  name: 'custom',
  setup() {
    // custom setup
    return {
      teardown() {
        // called after all tests with this env have been run
      }
    }
  }
}
```


You also have access to default Vitest environments through `vitest/environments` entry:



ts
```
import { builtinEnvironments, populateGlobal } from 'vitest/environments'

console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime }
```


```
import { builtinEnvironments, populateGlobal } from 'vitest/environments'

console.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime }
```


Vitest also provides `populateGlobal` utility function, which can be used to move properties from object into the global namespace:



ts
```
interface PopulateOptions {
  // should non-class functions be bind to the global namespace
  bindFunctions?: boolean
}

interface PopulateResult {
  // a list of all keys that were copied, even if value doesn't exist on original object
  keys: Set<string>
  // a map of original object that might have been overridden with keys
  // you can return these values inside `teardown` function
  originals: Map<string | symbol, any>
}

export function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult
```


```
interface PopulateOptions {
  // should non-class functions be bind to the global namespace
  bindFunctions?: boolean
}

interface PopulateResult {
  // a list of all keys that were copied, even if value doesn't exist on original object
  keys: Set<string>
  // a map of original object that might have been overridden with keys
  // you can return these values inside `teardown` function
  originals: Map<string | symbol, any>
}

export function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/environment.html>

Extending Matchers
==================


Since Vitest is compatible with both Chai and Jest, you can use either the `chai.use` API or `expect.extend`, whichever you prefer.


This guide will explore extending matchers with `expect.extend`. If you are interested in Chai's API, check [their guide](https://www.chaijs.com/guide/plugins/).


To extend default matchers, call `expect.extend` with an object containing your matchers.



ts
```
expect.extend({
  toBeFoo(received, expected) {
    const { isNot } = this
    return {
      // do not alter your "pass" based on isNot. Vitest does it for you
      pass: received === 'foo',
      message: () => `${received} is${isNot ? ' not' : ''} foo`
    }
  }
})
```


```
expect.extend({
  toBeFoo(received, expected) {
    const { isNot } = this
    return {
      // do not alter your "pass" based on isNot. Vitest does it for you
      pass: received === 'foo',
      message: () => `${received} is${isNot ? ' not' : ''} foo`
    }
  }
})
```


If you are using TypeScript, since Vitest 0.31.0 you can extend default `Assertion` interface in an ambient declaration file (e.g: `vitest.d.ts`) with the code below:



ts
```
import type { Assertion, AsymmetricMatchersContaining } from 'vitest'

interface CustomMatchers<R = unknown> {
  toBeFoo(): R
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}
```


```
import type { Assertion, AsymmetricMatchersContaining } from 'vitest'

interface CustomMatchers<R = unknown> {
  toBeFoo(): R
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}
```



**WARNING**Don't forget to include the ambient declaration file in your `tsconfig.json`.



The return value of a matcher should be compatible with the following interface:



ts
```
interface MatcherResult {
  pass: boolean
  message: () => string
  // If you pass these, they will automatically appear inside a diff when
  // the matcher does not pass, so you don't need to print the diff yourself
  actual?: unknown
  expected?: unknown
}
```


```
interface MatcherResult {
  pass: boolean
  message: () => string
  // If you pass these, they will automatically appear inside a diff when
  // the matcher does not pass, so you don't need to print the diff yourself
  actual?: unknown
  expected?: unknown
}
```



**WARNING**If you create an asynchronous matcher, don't forget to `await` the result (`await expect('foo').toBeFoo()`) in the test itself.



The first argument inside a matcher's function is the received value (the one inside `expect(received)`). The rest are arguments passed directly to the matcher.


Matcher function have access to `this` context with the following properties:


* `isNot`


Returns true, if matcher was called on `not` (`expect(received).not.toBeFoo()`).
* `promise`


If matcher was called on `resolved/rejected`, this value will contain the name of modifier. Otherwise, it will be an empty string.
* `equals`


This is a utility function that allows you to compare two values. It will return `true` if values are equal, `false` otherwise. This function is used internally for almost every matcher. It supports objects with asymmetric matchers by default.
* `utils`


This contains a set of utility functions that you can use to display messages.


`this` context also contains information about the current test. You can also get it by calling `expect.getState()`. The most useful properties are:


* `currentTestName`


Full name of the current test (including describe block).
* `testPath`


Path to the current test.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/extending-matchers.html>

IDE Integrations
================


VS Code `Official`
------------------


![]


[GitHub](https://github.com/vitest-dev/vscode) | [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=ZixuanChen.vitest-explorer)


![](https://i.ibb.co/bJCbCf2/202203292020.gif)


JetBrains IDE
-------------


WebStorm, PhpStorm, IntelliJ IDEA Ultimate, and other JetBrains IDEs come with built-in support for Vitest.


![]


[WebStorm Help](https://www.jetbrains.com/help/webstorm/vitest.html) | [IntelliJ IDEA Ultimate Help](https://www.jetbrains.com/help/idea/vitest.html) | [PhpStorm Help](https://www.jetbrains.com/help/phpstorm/vitest.html)


![Vitest WebStorm Demo](https://raw.githubusercontent.com/kricact/WS-info/main/gifs/vitest-run-all.gif)


Wallaby.js `Paid (free for OSS)`
--------------------------------


Created by [The Wallaby Team](https://wallabyjs.com)


[Wallaby.js](https://wallabyjs.com) runs your Vitest tests immediately as you type, highlighting results in your IDE right next to your code.


![]


[VS Code](https://marketplace.visualstudio.com/items?itemName=WallabyJs.wallaby-vscode) | [JetBrains](https://plugins.jetbrains.com/plugin/15742-wallaby) | [Visual Studio](https://marketplace.visualstudio.com/items?itemName=vs-publisher-999439.WallabyjsforVisualStudio2022) | [Sublime Text](https://packagecontrol.io/packages/Wallaby)


![Wallaby VS Code Demo](https://wallabyjs.com/assets/img/vitest_demo.gif)



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/ide.html>

Migration Guide
===============


Migrating from Jest
-------------------


Vitest has been designed with a Jest compatible API, in order to make the migration from Jest as simple as possible. Despite those efforts, you may still run into the following differences:


**Globals as a Default**


Jest has their [globals API](https://jestjs.io/docs/api) enabled by default. Vitest does not. You can either enable globals via [the `globals` configuration setting](../config/index#globals) or update your code to use imports from the `vitest` module instead.


If you decide to keep globals disabled, be aware that common libraries like [`testing-library`](https://testing-library.com/) will not run auto DOM [cleanup](https://testing-library.com/docs/svelte-testing-library/api/#cleanup).


**Module mocks**


When mocking a module in Jest, the factory argument's return value is the default export. In Vitest, the factory argument has to return an object with each export explicitly defined. For example, the following `jest.mock` would have to be updated as follows:



diff
```
- jest.mock('./some-path', () => 'hello')
+ vi.mock('./some-path', () => ({
+   default: 'hello',
+ })
```


```
- jest.mock('./some-path', () => 'hello')
+ vi.mock('./some-path', () => ({
+   default: 'hello',
+ })
```


For more details please refer to the [`vi.mock` api section](../api/vi#vi-mock).


**Auto-Mocking Behaviour**


Unlike Jest, mocked modules in `<root>/__mocks__` are not loaded unless `vi.mock()` is called. If you need them to be mocked in every test, like in Jest, you can mock them inside [`setupFiles`](../config/index#setupfiles).


**Importing the original of a mocked package**


If you are only partially mocking a package, you might have previously used Jest's function `requireActual`. In Vitest, you should replace these calls with `vi.importActual`.



diff
```
- const { cloneDeep } = jest.requireActual('lodash/cloneDeep')
+ const { cloneDeep } = await vi.importActual('lodash/cloneDeep')
```


```
- const { cloneDeep } = jest.requireActual('lodash/cloneDeep')
+ const { cloneDeep } = await vi.importActual('lodash/cloneDeep')
```


**Jasmine API**


Jest exports various [`jasmine`](https://jasmine.github.io/) globals (such as `jasmine.any()`). Any such instances will need to be migrated to [their Vitest counterparts](../api/index).


**Envs**


Just like Jest, Vitest sets `NODE_ENV` to `test`, if it wasn't set before. Vitest also has a counterpart for `JEST_WORKER_ID` called `VITEST_POOL_ID` (always less than or equal to `maxThreads`), so if you rely on it, don't forget to rename it. Vitest also exposes `VITEST_WORKER_ID` which is a unique ID of a running worker - this number is not affected by `maxThreads`, and will increase with each created worker.


If you want to modify the envs, 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) to do it also in Vitest.


**Done Callback**


From Vitest v0.10.0, the callback style of declaring tests is deprecated. You can rewrite them to use `async`/`await` functions, or use Promise to mimic the callback style.



diff
```
- it('should work', (done) => {
+ it('should work', () => new Promise(done => {
    // ...
    done()
- })
+ }))
```


```
- it('should work', (done) => {
+ it('should work', () => new Promise(done => {
    // ...
    done()
- })
+ }))
```


**Hooks**


`beforeAll`/`beforeEach` hooks may return [teardown function](../api/index#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`:



diff
```
- beforeEach(() => setActivePinia(createTestingPinia()))
+ beforeEach(() => { setActivePinia(createTestingPinia()) })
```


```
- beforeEach(() => setActivePinia(createTestingPinia()))
+ beforeEach(() => { setActivePinia(createTestingPinia()) })
```


**Types**


Vitest doesn't expose a lot of types on `Vi` namespace, it exists mainly for compatibility with matchers, so you might need to import types directly from `vitest` instead of relying on `Vi` namespace:



diff
```
- let fn: jest.Mock<string, [string]>
+ import type { Mock } from 'vitest'
+ let fn: Mock<[string], string>
```


```
- let fn: jest.Mock<string, [string]>
+ import type { Mock } from 'vitest'
+ let fn: Mock<[string], string>
```


Also, Vitest has `Args` type as a first argument instead of `Returns`, as you can see in diff.


**Timers**


Vitest doesn't support Jest's legacy timers.


**Vue Snapshots**


This is not a Jest-specific feature, but if you previously were using Jest with vue-cli preset, you will need to install [`jest-serializer-vue`](https://github.com/eddyerburgh/jest-serializer-vue) package, and use it inside [setupFiles](../config/index#setupfiles):


`vite.config.js`



js
```
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    setupFiles: ['./tests/unit/setup.js']
  }
})
```


```
import { defineConfig } from 'vite'

export default defineConfig({
  test: {
    setupFiles: ['./tests/unit/setup.js']
  }
})
```


`tests/unit/setup.js`



js
```
import vueSnapshotSerializer from 'jest-serializer-vue'

expect.addSnapshotSerializer(vueSnapshotSerializer)
```


```
import vueSnapshotSerializer from 'jest-serializer-vue'

expect.addSnapshotSerializer(vueSnapshotSerializer)
```


Otherwise your snapshots will have a lot of escaped `"` characters.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/migration.html>

Common Errors
=============


Cannot find module './relative-path'
------------------------------------


If you receive an error that module cannot be found, it might mean several different things:


* 1. You misspelled the path. Make sure the path is correct.
* 2. It's possible that your rely on `baseUrl` in your `tsconfig.json`. Vite doesn't take into account `tsconfig.json` by default, so you might need to install [`vite-tsconfig-paths`](https://www.npmjs.com/package/vite-tsconfig-paths) yourself, if you rely on this behaviour.



ts
```
import { defineConfig } from 'vitest/config'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [tsconfigPaths()]
})
```


```
import { defineConfig } from 'vitest/config'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [tsconfigPaths()]
})
```


Or rewrite your path to not be relative to root:



diff
```
- import helpers from 'src/helpers'
+ import helpers from '../src/helpers'
```


```
- import helpers from 'src/helpers'
+ import helpers from '../src/helpers'
```


* 3. Make sure you don't have relative [aliases](../config/index#alias). Vite treats them as relative to the file where the import is instead of the root.



diff
```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    alias: {
-     '@/': './src/',
+     '@/': new URL('./src/', import.meta.url).pathname,
    }
  }
})
```


```
import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    alias: {
-     '@/': './src/',
+     '@/': new URL('./src/', import.meta.url).pathname,
    }
  }
})
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/guide/common-errors.html>

Mock Functions
==============


You can create a spy function (mock) to track its execution with `vi.fn` method. If you want to track a method on an already created object, you can use `vi.spyOn` method:



js
```
import { vi } from 'vitest'

const fn = vi.fn()
fn('hello world')
fn.mock.calls[0] === ['hello world']

const market = {
  getApples: () => 100
}

const getApplesSpy = vi.spyOn(market, 'getApples')
market.getApples()
getApplesSpy.mock.calls.length === 1
```


```
import { vi } from 'vitest'

const fn = vi.fn()
fn('hello world')
fn.mock.calls[0] === ['hello world']

const market = {
  getApples: () => 100
}

const getApplesSpy = vi.spyOn(market, 'getApples')
market.getApples()
getApplesSpy.mock.calls.length === 1
```


You should use spy assertions (e.g., [`toHaveBeenCalled`](expect#tohavebeencalled)) on [`expect`](expect) to assert spy result. This API reference describes available properties and methods to manipulate spy behavior.


getMockName
-----------


* **Type:** `() => string`


Use it to return the name given to mock with method `.mockName(name)`.


mockClear
---------


* **Type:** `() => MockInstance`


Clears all information about every call. After calling it, [`spy.mock.calls`](#mock-calls), [`spy.mock.results`](#mock-results) will return empty arrays. It is useful if you need to clean up spy between different assertions.


If you want this method to be called before each test automatically, you can enable [`clearMocks`](../config/index#clearmocks) setting in config.


mockName
--------


* **Type:** `(name: string) => MockInstance`


Sets internal mock name. Useful to see what mock has failed the assertion.


mockImplementation
------------------


* **Type:** `(fn: Function) => MockInstance`


Accepts a function that will be used as an implementation of the mock.


For example:



ts
```
const mockFn = vi.fn().mockImplementation(apples => apples + 1)
// or: vi.fn(apples => apples + 1);

const NelliesBucket = mockFn(0)
const BobsBucket = mockFn(1)

NelliesBucket === 1 // true
BobsBucket === 2 // true

mockFn.mock.calls[0][0] === 0 // true
mockFn.mock.calls[1][0] === 1 // true
```


```
const mockFn = vi.fn().mockImplementation(apples => apples + 1)
// or: vi.fn(apples => apples + 1);

const NelliesBucket = mockFn(0)
const BobsBucket = mockFn(1)

NelliesBucket === 1 // true
BobsBucket === 2 // true

mockFn.mock.calls[0][0] === 0 // true
mockFn.mock.calls[1][0] === 1 // true
```


mockImplementationOnce
----------------------


* **Type:** `(fn: Function) => MockInstance`


Accepts a function that will be used as an implementation of the mock for one call to the mocked function. Can be chained so that multiple function calls produce different results.



ts
```
const myMockFn = vi
  .fn()
  .mockImplementationOnce(() => true)
  .mockImplementationOnce(() => false)

myMockFn() // true
myMockFn() // false
```


```
const myMockFn = vi
  .fn()
  .mockImplementationOnce(() => true)
  .mockImplementationOnce(() => false)

myMockFn() // true
myMockFn() // false
```


When the mocked function runs out of implementations, it will invoke the default implementation that was set with `vi.fn(() => defaultValue)` or `.mockImplementation(() => defaultValue)` if they were called:



ts
```
const myMockFn = vi
  .fn(() => 'default')
  .mockImplementationOnce(() => 'first call')
  .mockImplementationOnce(() => 'second call')

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn())
```


```
const myMockFn = vi
  .fn(() => 'default')
  .mockImplementationOnce(() => 'first call')
  .mockImplementationOnce(() => 'second call')

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn())
```


withImplementation
------------------


* **Type:** `(fn: Function, callback: () => void) => MockInstance`
* **Type:** `(fn: Function, callback: () => Promise<unknown>) => Promise<MockInstance>`


Overrides the original mock implementation temporarily while the callback is being executed.



js
```
const myMockFn = vi.fn(() => 'original')

myMockFn.withImplementation(() => 'temp', () => {
  myMockFn() // 'temp'
})

myMockFn() // 'original'
```


```
const myMockFn = vi.fn(() => 'original')

myMockFn.withImplementation(() => 'temp', () => {
  myMockFn() // 'temp'
})

myMockFn() // 'original'
```


Can be used with an asynchronous callback. The method has to be awaited to use the original implementation afterward.



ts
```
test('async callback', () => {
  const myMockFn = vi.fn(() => 'original')

  // We await this call since the callback is async
  await myMockFn.withImplementation(
    () => 'temp',
    async () => {
      myMockFn() // 'temp'
    },
  )

  myMockFn() // 'original'
})
```


```
test('async callback', () => {
  const myMockFn = vi.fn(() => 'original')

  // We await this call since the callback is async
  await myMockFn.withImplementation(
    () => 'temp',
    async () => {
      myMockFn() // 'temp'
    },
  )

  myMockFn() // 'original'
})
```


Also, it takes precedence over the [`mockImplementationOnce`](mock#mockimplementationonce).


mockRejectedValue
-----------------


* **Type:** `(value: any) => MockInstance`


Accepts an error that will be rejected, when async function will be called.



ts
```
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'))

await asyncMock() // throws "Async error"
```


```
const asyncMock = vi.fn().mockRejectedValue(new Error('Async error'))

await asyncMock() // throws "Async error"
```


mockRejectedValueOnce
---------------------


* **Type:** `(value: any) => MockInstance`


Accepts a value that will be rejected for one call to the mock function. If chained, every consecutive call will reject passed value.



ts
```
const asyncMock = vi
  .fn()
  .mockResolvedValueOnce('first call')
  .mockRejectedValueOnce(new Error('Async error'))

await asyncMock() // first call
await asyncMock() // throws "Async error"
```


```
const asyncMock = vi
  .fn()
  .mockResolvedValueOnce('first call')
  .mockRejectedValueOnce(new Error('Async error'))

await asyncMock() // first call
await asyncMock() // throws "Async error"
```


mockReset
---------


* **Type:** `() => MockInstance`


Does what `mockClear` does and makes inner implementation an empty function (returning `undefined`, when invoked). This is useful when you want to completely reset a mock back to its initial state.


If you want this method to be called before each test automatically, you can enable [`mockReset`](../config/index#mockreset) setting in config.


mockRestore
-----------


* **Type:** `() => MockInstance`


Does what `mockReset` does and restores inner implementation to the original function.


Note that restoring mock from `vi.fn()` will set implementation to an empty function that returns `undefined`. Restoring a `vi.fn(impl)` will restore implementation to `impl`.


If you want this method to be called before each test automatically, you can enable [`restoreMocks`](../config/index#restoreMocks) setting in config.


mockResolvedValue
-----------------


* **Type:** `(value: any) => MockInstance`


Accepts a value that will be resolved, when async function will be called.



ts
```
const asyncMock = vi.fn().mockResolvedValue(43)

await asyncMock() // 43
```


```
const asyncMock = vi.fn().mockResolvedValue(43)

await asyncMock() // 43
```


mockResolvedValueOnce
---------------------


* **Type:** `(value: any) => MockInstance`


Accepts a value that will be resolved for one call to the mock function. If chained, every consecutive call will resolve passed value.



ts
```
const asyncMock = vi
  .fn()
  .mockResolvedValue('default')
  .mockResolvedValueOnce('first call')
  .mockResolvedValueOnce('second call')

await asyncMock() // first call
await asyncMock() // second call
await asyncMock() // default
await asyncMock() // default
```


```
const asyncMock = vi
  .fn()
  .mockResolvedValue('default')
  .mockResolvedValueOnce('first call')
  .mockResolvedValueOnce('second call')

await asyncMock() // first call
await asyncMock() // second call
await asyncMock() // default
await asyncMock() // default
```


mockReturnThis
--------------


* **Type:** `() => MockInstance`


Sets inner implementation to return `this` context.


mockReturnValue
---------------


* **Type:** `(value: any) => MockInstance`


Accepts a value that will be returned whenever the mock function is called.



ts
```
const mock = vi.fn()
mock.mockReturnValue(42)
mock() // 42
mock.mockReturnValue(43)
mock() // 43
```


```
const mock = vi.fn()
mock.mockReturnValue(42)
mock() // 42
mock.mockReturnValue(43)
mock() // 43
```


mockReturnValueOnce
-------------------


* **Type:** `(value: any) => MockInstance`


Accepts a value that will be returned for one call to the mock function. If chained, every consecutive call will return the passed value. When there are no more `mockReturnValueOnce` values to use, call a function specified by `mockImplementation` or other `mockReturn*` methods.



ts
```
const myMockFn = vi
  .fn()
  .mockReturnValue('default')
  .mockReturnValueOnce('first call')
  .mockReturnValueOnce('second call')

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn())
```


```
const myMockFn = vi
  .fn()
  .mockReturnValue('default')
  .mockReturnValueOnce('first call')
  .mockReturnValueOnce('second call')

// 'first call', 'second call', 'default', 'default'
console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn())
```


mock.calls
----------


This is an array containing all arguments for each call. One item of the array is the arguments of that call.



js
```
const fn = vi.fn()

fn('arg1', 'arg2')
fn('arg3', 'arg4')

fn.mock.calls === [
  ['arg1', 'arg2'], // first call
  ['arg3', 'arg4'], // second call
]
```


```
const fn = vi.fn()

fn('arg1', 'arg2')
fn('arg3', 'arg4')

fn.mock.calls === [
  ['arg1', 'arg2'], // first call
  ['arg3', 'arg4'], // second call
]
```


mock.lastCall
-------------


This contains the arguments of the last call. If spy wasn't called, will return `undefined`.


mock.results
------------


This is an array containing all values, that were `returned` from the function. One item of the array is an object with properties `type` and `value`. Available types are:


* `'return'` - function returned without throwing.
* `'throw'` - function threw a value.


The `value` property contains returned value or thrown error.



js
```
const fn = vi.fn()

const result = fn() // returned 'result'

try {
  fn() // threw Error
}
catch {}

fn.mock.results === [
  // first result
  {
    type: 'return',
    value: 'result',
  },
  // last result
  {
    type: 'throw',
    value: Error,
  },
]
```


```
const fn = vi.fn()

const result = fn() // returned 'result'

try {
  fn() // threw Error
}
catch {}

fn.mock.results === [
  // first result
  {
    type: 'return',
    value: 'result',
  },
  // last result
  {
    type: 'throw',
    value: Error,
  },
]
```


mock.instances
--------------


This is an array containing all instances that were instantiated when mock was called with a `new` keyword. Note, this is an actual context (`this`) of the function, not a return value.



**WARNING**If mock was instantiated with `new MyClass()`, then `mock.instances` will be an array with one value:



js
```
const MyClass = vi.fn()
const a = new MyClass()

MyClass.mock.instances[0] === a
```


```
const MyClass = vi.fn()
const a = new MyClass()

MyClass.mock.instances[0] === a
```


If you return a value from constructor, it will not be in `instances` array, but instead inside `results`:



js
```
const Spy = vi.fn(() => ({ method: vi.fn() }))
const a = new Spy()

Spy.mock.instances[0] !== a
Spy.mock.results[0] === a
```


```
const Spy = vi.fn(() => ({ method: vi.fn() }))
const a = new Spy()

Spy.mock.instances[0] !== a
Spy.mock.results[0] === a
```




 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/api/mock.html>

Vi
==


Vitest provides utility functions to help you out through its `vi` helper. You can access it globally (when [globals configuration](../config/index#globals) is **enabled**), or import from `vitest`:



js
```
import { vi } from 'vitest'
```


```
import { vi } from 'vitest'
```


vi.advanceTimersByTime
----------------------


* **Type:** `(ms: number) => Vitest`


Works just like `runAllTimers`, but will end after passed milliseconds. For example this will log `1, 2, 3` and will not throw:



ts
```
let i = 0
setInterval(() => console.log(++i), 50)

vi.advanceTimersByTime(150)
```


```
let i = 0
setInterval(() => console.log(++i), 50)

vi.advanceTimersByTime(150)
```


### vi.advanceTimersByTimeAsync


* **Type:** `(ms: number) => Promise<Vitest>`


Works just like `runAllTimersAsync`, but will end after passed milliseconds. This will include asynchronously set timers. For example this will log `1, 2, 3` and will not throw:



ts
```
let i = 0
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50)

await vi.advanceTimersByTimeAsync(150)
```


```
let i = 0
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50)

await vi.advanceTimersByTimeAsync(150)
```


vi.advanceTimersToNextTimer
---------------------------


* **Type:** `() => Vitest`


Will call next available timer. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself.



ts
```
let i = 0
setInterval(() => console.log(++i), 50)

vi.advanceTimersToNextTimer() // log 1
  .advanceTimersToNextTimer() // log 2
  .advanceTimersToNextTimer() // log 3
```


```
let i = 0
setInterval(() => console.log(++i), 50)

vi.advanceTimersToNextTimer() // log 1
  .advanceTimersToNextTimer() // log 2
  .advanceTimersToNextTimer() // log 3
```


### vi.advanceTimersToNextTimerAsync


* **Type:** `() => Promise<Vitest>`


Will call next available timer even if it was set asynchronously. Useful to make assertions between each timer call. You can chain call it to manage timers by yourself.



ts
```
let i = 0
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50)

vi.advanceTimersToNextTimerAsync() // log 1
  .advanceTimersToNextTimerAsync() // log 2
  .advanceTimersToNextTimerAsync() // log 3
```


```
let i = 0
setInterval(() => Promise.resolve().then(() => console.log(++i)), 50)

vi.advanceTimersToNextTimerAsync() // log 1
  .advanceTimersToNextTimerAsync() // log 2
  .advanceTimersToNextTimerAsync() // log 3
```


vi.getTimerCount
----------------


* **Type:** `() => number`


Get the number of waiting timers.


vi.clearAllMocks
----------------


Will call [`.mockClear()`](mock#mockclear) on all spies. This will clear mock history, but not reset its implementation to the default one.


vi.clearAllTimers
-----------------


Removes all timers that are scheduled to run. These timers will never run in the future.


vi.dynamicImportSettled
-----------------------


Wait for all imports to load. Useful, if you have a synchronous call that starts importing a module, that you cannot wait otherwise.


vi.fn
-----


* **Type:** `(fn?: Function) => CallableMockInstance`


Creates a spy on a function, though can be initiated without one. Every time a function is invoked, it stores its call arguments, returns, and instances. Also, you can manipulate its behavior with [methods](mock). If no function is given, mock will return `undefined`, when invoked.



ts
```
const getApples = vi.fn(() => 0)

getApples()

expect(getApples).toHaveBeenCalled()
expect(getApples).toHaveReturnedWith(0)

getApples.mockReturnValueOnce(5)

const res = getApples()
expect(res).toBe(5)
expect(getApples).toHaveNthReturnedWith(2, 5)
```


```
const getApples = vi.fn(() => 0)

getApples()

expect(getApples).toHaveBeenCalled()
expect(getApples).toHaveReturnedWith(0)

getApples.mockReturnValueOnce(5)

const res = getApples()
expect(res).toBe(5)
expect(getApples).toHaveNthReturnedWith(2, 5)
```


vi.getMockedSystemTime
----------------------


* **Type**: `() => Date | null`


Returns mocked current date that was set using `setSystemTime`. If date is not mocked, will return `null`.


vi.getRealSystemTime
--------------------


* **Type**: `() => number`


When using `vi.useFakeTimers`, `Date.now` calls are mocked. If you need to get real time in milliseconds, you can call this function.


vi.hoisted
----------


* **Type**: `<T>(factory: () => T) => T`
* **Version**: Since Vitest 0.31.0


All static `import` statements in ES modules are hoisted to top of the file, so any code that is define before the imports will actually be executed after imports are evaluated.


Hovewer it can be useful to invoke some side effect like mocking dates before importing a module.


To bypass this limitation, you can rewrite static imports into dynamic ones like this:



diff
```
callFunctionWithSideEffect()
- import { value } from './some/module.ts'
+ const { value } = await import('./some/module.ts')
```


```
callFunctionWithSideEffect()
- import { value } from './some/module.ts'
+ const { value } = await import('./some/module.ts')
```


When running `vitest`, you can do this automatically by using `vi.hoisted` method.



diff
```
- callFunctionWithSideEffect()
import { value } from './some/module.ts'
+ vi.hoisted(() => callFunctionWithSideEffect())
```


```
- callFunctionWithSideEffect()
import { value } from './some/module.ts'
+ vi.hoisted(() => callFunctionWithSideEffect())
```


This method returns the value that was returned from the factory. You can use that value in your `vi.mock` factories if you need an easy access to locally defined variables:



ts
```
import { expect, vi } from 'vitest'
import { originalMethod } from './path/to/module.js'

const { mockedMethod } = vi.hoisted(() => {
  return { mockedMethod: vi.fn() }
})

vi.mock('./path/to/module.js', () => {
  return { originalMethod: mockedMethod }
})

mockedMethod.mockReturnValue(100)
expect(originalMethod()).toBe(100)
```


```
import { expect, vi } from 'vitest'
import { originalMethod } from './path/to/module.js'

const { mockedMethod } = vi.hoisted(() => {
  return { mockedMethod: vi.fn() }
})

vi.mock('./path/to/module.js', () => {
  return { originalMethod: mockedMethod }
})

mockedMethod.mockReturnValue(100)
expect(originalMethod()).toBe(100)
```


vi.mock
-------


* **Type**: `(path: string, factory?: () => unknown) => void`


Substitutes all imported modules from provided `path` with another module. You can use configured Vite aliases inside a path. The call to `vi.mock` is hoisted, so it doesn't matter where you call it. It will always be executed before all imports. If you need to reference some variables outside of its scope, you can defined them inside [`vi.hoisted`](vi#vi-hoisted) and reference inside `vi.mock`.



**WARNING**`vi.mock` works only for modules that were imported with the `import` keyword. It doesn't work with `require`.


Vitest statically analyzes your files to hoist `vi.mock`. It means that you cannot use `vi` that was not imported directly from `vitest` package (for example, from some utility file). To fix this, always use `vi.mock` with `vi` imported from `vitest`, or enable [`globals`](../config/index#globals) config option.




**WARNING**Mocking modules is not currently supported in the [browser mode](../guide/browser). You can track this feature in the GitHub [issue](https://github.com/vitest-dev/vitest/issues/3046).



If `factory` is defined, all imports will return its result. Vitest calls factory only once and caches result for all subsequent imports until [`vi.unmock`](#vi-unmock) or [`vi.doUnmock`](#vi-dounmock) is called.


Unlike in `jest`, the factory can be asynchronous, so you can use [`vi.importActual`](#vi-importactual) or a helper, received as the first argument, inside to get the original module.



ts
```
vi.mock('./path/to/module.js', async (importOriginal) => {
  const mod = await importOriginal()
  return {
    ...mod,
    // replace some exports
    namedExport: vi.fn(),
  }
})
```


```
vi.mock('./path/to/module.js', async (importOriginal) => {
  const mod = await importOriginal()
  return {
    ...mod,
    // replace some exports
    namedExport: vi.fn(),
  }
})
```



**WARNING**`vi.mock` is hoisted (in other words, *moved*) to **top of the file**. It means that whenever you write it (be it inside `beforeEach` or `test`), it will actually be called before that.


This also means that you cannot use any variables inside the factory that are defined outside the factory.


If you need to use variables inside the factory, try [`vi.doMock`](#vi-domock). It works the same way but isn't hoisted. Beware that it only mocks subsequent imports.


You can also reference variables defined by `vi.hoisted` method if it was declared before `vi.mock`:



ts
```
import { namedExport } from './path/to/module.js'

const mocks = vi.hoisted(() => {
  return {
    namedExport: vi.fn(),
  }
})

vi.mock('./path/to/module.js', () => {
  return {
    namedExport: mocks.namedExport,
  }
})

vi.mocked(namedExport).mockReturnValue(100)

expect(namedExport()).toBe(100)
expect(namedExport).toBe(mocks.namedExport)
```


```
import { namedExport } from './path/to/module.js'

const mocks = vi.hoisted(() => {
  return {
    namedExport: vi.fn(),
  }
})

vi.mock('./path/to/module.js', () => {
  return {
    namedExport: mocks.namedExport,
  }
})

vi.mocked(namedExport).mockReturnValue(100)

expect(namedExport()).toBe(100)
expect(namedExport).toBe(mocks.namedExport)
```




**WARNING**If you are mocking a module with default export, you will need to provide a `default` key within the returned factory function object. This is an ES modules-specific caveat, therefore `jest` documentation may differ as `jest` uses CommonJS modules. For example,



ts
```
vi.mock('./path/to/module.js', () => {
  return {
    default: { myDefaultKey: vi.fn() },
    namedExport: vi.fn(),
    // etc...
  }
})
```


```
vi.mock('./path/to/module.js', () => {
  return {
    default: { myDefaultKey: vi.fn() },
    namedExport: vi.fn(),
    // etc...
  }
})
```



If there is a `__mocks__` folder alongside a file that you are mocking, and the factory is not provided, Vitest will try to find a file with the same name in the `__mocks__` subfolder and use it as an actual module. If you are mocking a dependency, Vitest will try to find a `__mocks__` folder in the [root](../config/index#root) of the project (default is `process.cwd()`). You can tell Vitest where the dependencies are located through the [deps.moduleDirectories](../config/index#deps-moduledirectories) config option.


For example, you have this file structure:




```
- __mocks__
  - axios.js
- src
  __mocks__
    - increment.js
  - increment.js
- tests
  - increment.test.js
```


```
- __mocks__
  - axios.js
- src
  __mocks__
    - increment.js
  - increment.js
- tests
  - increment.test.js
```


If you call `vi.mock` in a test file without a factory provided, it will find a file in the `__mocks__` folder to use as a module:



ts
```
// increment.test.js
import { vi } from 'vitest'

// axios is a default export from `__mocks__/axios.js`
import axios from 'axios'

// increment is a named export from `src/__mocks__/increment.js`
import { increment } from '../increment.js'

vi.mock('axios')
vi.mock('../increment.js')

axios.get(`/apples/${increment(1)}`)
```


```
// increment.test.js
import { vi } from 'vitest'

// axios is a default export from `__mocks__/axios.js`
import axios from 'axios'

// increment is a named export from `src/__mocks__/increment.js`
import { increment } from '../increment.js'

vi.mock('axios')
vi.mock('../increment.js')

axios.get(`/apples/${increment(1)}`)
```



**WARNING**Beware that if you don't call `vi.mock`, modules **are not** mocked automatically. To replicate Jest's automocking behaviour, you can call `vi.mock` for each required module inside [`setupFiles`](../config/index#setupfiles).



If there is no `__mocks__` folder or a factory provided, Vitest will import the original module and auto-mock all its exports. For the rules applied, see [algorithm](../guide/mocking#automocking-algorithm).


vi.doMock
---------


* **Type**: `(path: string, factory?: () => unknown) => void`


The same as [`vi.mock`](#vi-mock), but it's not hoisted at the top of the file, so you can reference variables in the global file scope. The next import of the module will be mocked. This will not mock modules that were imported before this was called.



ts
```
// ./increment.js
export function increment(number) {
  return number + 1
}
```


```
// ./increment.js
export function increment(number) {
  return number + 1
}
```



ts
```
import { beforeEach, test } from 'vitest'
import { increment } from './increment.js'

// the module is not mocked, because vi.doMock is not called yet
increment(1) === 2

let mockedIncrement = 100

beforeEach(() => {
  // you can access variables inside a factory
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }))
})

test('importing the next module imports mocked one', async () => {
  // original import WAS NOT MOCKED, because vi.doMock is evaluated AFTER imports
  expect(increment(1)).toBe(2)
  const { increment: mockedIncrement } = await import('./increment.js')
  // new import returns mocked module
  expect(mockedIncrement(1)).toBe(101)
  expect(mockedIncrement(1)).toBe(102)
  expect(mockedIncrement(1)).toBe(103)
})
```


```
import { beforeEach, test } from 'vitest'
import { increment } from './increment.js'

// the module is not mocked, because vi.doMock is not called yet
increment(1) === 2

let mockedIncrement = 100

beforeEach(() => {
  // you can access variables inside a factory
  vi.doMock('./increment.js', () => ({ increment: () => ++mockedIncrement }))
})

test('importing the next module imports mocked one', async () => {
  // original import WAS NOT MOCKED, because vi.doMock is evaluated AFTER imports
  expect(increment(1)).toBe(2)
  const { increment: mockedIncrement } = await import('./increment.js')
  // new import returns mocked module
  expect(mockedIncrement(1)).toBe(101)
  expect(mockedIncrement(1)).toBe(102)
  expect(mockedIncrement(1)).toBe(103)
})
```


vi.mocked
---------


* **Type**: `<T>(obj: T, deep?: boolean) => MaybeMockedDeep<T>`
* **Type**: `<T>(obj: T, options?: { partial?: boolean; deep?: boolean }) => MaybePartiallyMockedDeep<T>`


Type helper for TypeScript. In reality just returns the object that was passed.


When `partial` is `true` it will expect a `Partial<T>` as a return value.



ts
```
import example from './example.js'

vi.mock('./example.js')

test('1+1 equals 2', async () => {
  vi.mocked(example.calc).mockRestore()

  const res = example.calc(1, '+', 1)

  expect(res).toBe(2)
})
```


```
import example from './example.js'

vi.mock('./example.js')

test('1+1 equals 2', async () => {
  vi.mocked(example.calc).mockRestore()

  const res = example.calc(1, '+', 1)

  expect(res).toBe(2)
})
```


vi.importActual
---------------


* **Type**: `<T>(path: string) => Promise<T>`


Imports module, bypassing all checks if it should be mocked. Can be useful if you want to mock module partially.



ts
```
vi.mock('./example.js', async () => {
  const axios = await vi.importActual('./example.js')

  return { ...axios, get: vi.fn() }
})
```


```
vi.mock('./example.js', async () => {
  const axios = await vi.importActual('./example.js')

  return { ...axios, get: vi.fn() }
})
```


vi.importMock
-------------


* **Type**: `<T>(path: string) => Promise<MaybeMockedDeep<T>>`


Imports a module with all of its properties (including nested properties) mocked. Follows the same rules that [`vi.mock`](#vi-mock) follows. For the rules applied, see [algorithm](../guide/mocking#automocking-algorithm).


vi.resetAllMocks
----------------


Will call [`.mockReset()`](mock#mockreset) on all spies. This will clear mock history and reset its implementation to an empty function (will return `undefined`).


vi.resetConfig
--------------


* **Type**: `RuntimeConfig`


If [`vi.setConfig`](#vi-setconfig) was called before, this will reset config to the original state.


vi.resetModules
---------------


* **Type**: `() => Vitest`


Resets modules registry by clearing cache of all modules. This allows modules to be reevaluated when reimported. Top-level imports cannot be reevaluated. Might be useful to isolate modules where local state conflicts between tests.



ts
```
import { vi } from 'vitest'

import { data } from './data.js' // Will not get reevaluated beforeEach test

beforeEach(() => {
  vi.resetModules()
})

test('change state', async () => {
  const mod = await import('./some/path.js') // Will get reevaluated
  mod.changeLocalState('new value')
  expect(mod.getLocalState()).toBe('new value')
})

test('module has old state', async () => {
  const mod = await import('./some/path.js') // Will get reevaluated
  expect(mod.getLocalState()).toBe('old value')
})
```


```
import { vi } from 'vitest'

import { data } from './data.js' // Will not get reevaluated beforeEach test

beforeEach(() => {
  vi.resetModules()
})

test('change state', async () => {
  const mod = await import('./some/path.js') // Will get reevaluated
  mod.changeLocalState('new value')
  expect(mod.getLocalState()).toBe('new value')
})

test('module has old state', async () => {
  const mod = await import('./some/path.js') // Will get reevaluated
  expect(mod.getLocalState()).toBe('old value')
})
```



**WARNING**Does not reset mocks registry. To clear mocks registry, use [`vi.unmock`](#vi-unmock) or [`vi.doUnmock`](#vi-dounmock).



vi.restoreAllMocks
------------------


Will call [`.mockRestore()`](mock#mockrestore) on all spies. This will clear mock history and reset its implementation to the original one.


vi.restoreCurrentDate
---------------------


* **Type:** `() => void`


Restores `Date` back to its native implementation.


vi.stubEnv
----------


* **Type:** `(name: string, value: string) => Vitest`
* **Version:** Since Vitest 0.26.0


Changes the value of environmental variable on `process.env` and `import.meta.env`. You can restore its value by calling `vi.unstubAllEnvs`.



ts
```
import { vi } from 'vitest'

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling "vi.stubEnv"

vi.stubEnv('NODE_ENV', 'production')

process.env.NODE_ENV === 'production'
import.meta.env.NODE_ENV === 'production'
// doesn't change other envs
import.meta.env.MODE === 'development'
```


```
import { vi } from 'vitest'

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling "vi.stubEnv"

vi.stubEnv('NODE_ENV', 'production')

process.env.NODE_ENV === 'production'
import.meta.env.NODE_ENV === 'production'
// doesn't change other envs
import.meta.env.MODE === 'development'
```



**TIP**You can also change the value by simply assigning it, but you won't be able to use `vi.unstubAllEnvs` to restore previous value:



ts
```
import.meta.env.MODE = 'test'
```


```
import.meta.env.MODE = 'test'
```




**WARNING**Vitest transforms all `import.meta.env` calls into `process.env`, so they can be easily changed at runtime. Node.js only supports string values as env parameters, while Vite supports several built-in envs as boolean (namely, `SSR`, `DEV`, `PROD`). To mimic Vite, set "truthy" values as env: `''` instead of `false`, and `'1'` instead of `true`.


But beware that you cannot rely on `import.meta.env.DEV === false` in this case. Use `!import.meta.env.DEV`. This also affects simple assigning, not just `vi.stubEnv` method.



vi.unstubAllEnvs
----------------


* **Type:** `() => Vitest`
* **Version:** Since Vitest 0.26.0


Restores all `import.meta.env` and `process.env` values that were changed with `vi.stubEnv`. When it's called for the first time, Vitest remembers the original value and will store it, until `unstubAllEnvs` is called again.



ts
```
import { vi } from 'vitest'

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling stubEnv

vi.stubEnv('NODE_ENV', 'production')

process.env.NODE_ENV === 'production'
import.meta.env.NODE_ENV === 'production'

vi.stubEnv('NODE_ENV', 'staging')

process.env.NODE_ENV === 'staging'
import.meta.env.NODE_ENV === 'staging'

vi.unstubAllEnvs()

// restores to the value that were stored before the first "stubEnv" call
process.env.NODE_ENV === 'development'
import.meta.env.NODE_ENV === 'development'
```


```
import { vi } from 'vitest'

// `process.env.NODE_ENV` and `import.meta.env.NODE_ENV`
// are "development" before calling stubEnv

vi.stubEnv('NODE_ENV', 'production')

process.env.NODE_ENV === 'production'
import.meta.env.NODE_ENV === 'production'

vi.stubEnv('NODE_ENV', 'staging')

process.env.NODE_ENV === 'staging'
import.meta.env.NODE_ENV === 'staging'

vi.unstubAllEnvs()

// restores to the value that were stored before the first "stubEnv" call
process.env.NODE_ENV === 'development'
import.meta.env.NODE_ENV === 'development'
```


vi.stubGlobal
-------------


* **Type:** `(name: string | number | symbol, value: unknown) => Vitest`


Changes the value of global variable. You can restore its original value by calling `vi.unstubAllGlobals`.



ts
```
import { vi } from 'vitest'

// `innerWidth` is "0" before calling stubGlobal

vi.stubGlobal('innerWidth', 100)

innerWidth === 100
globalThis.innerWidth === 100
// if you are using jsdom or happy-dom
window.innerWidth === 100
```


```
import { vi } from 'vitest'

// `innerWidth` is "0" before calling stubGlobal

vi.stubGlobal('innerWidth', 100)

innerWidth === 100
globalThis.innerWidth === 100
// if you are using jsdom or happy-dom
window.innerWidth === 100
```



**TIP**You can also change the value by simply assigning it to `globalThis` or `window` (if you are using `jsdom` or `happy-dom` environment), but you won't be able to use `vi.unstubAllGlobals` to restore original value:



ts
```
globalThis.innerWidth = 100
// if you are using jsdom or happy-dom
window.innerWidth = 100
```


```
globalThis.innerWidth = 100
// if you are using jsdom or happy-dom
window.innerWidth = 100
```



vi.unstubAllGlobals
-------------------


* **Type:** `() => Vitest`
* **Version:** Since Vitest 0.26.0


Restores all global values on `globalThis`/`global` (and `window`/`top`/`self`/`parent`, if you are using `jsdom` or `happy-dom` environment) that were changed with `vi.stubGlobal`. When it's called for the first time, Vitest remembers the original value and will store it, until `unstubAllGlobals` is called again.



ts
```
import { vi } from 'vitest'

const Mock = vi.fn()

// IntersectionObserver is "undefined" before calling "stubGlobal"

vi.stubGlobal('IntersectionObserver', Mock)

IntersectionObserver === Mock
global.IntersectionObserver === Mock
globalThis.IntersectionObserver === Mock
// if you are using jsdom or happy-dom
window.IntersectionObserver === Mock

vi.unstubAllGlobals()

globalThis.IntersectionObserver === undefined
'IntersectionObserver' in globalThis === false
// throws ReferenceError, because it's not defined
IntersectionObserver === undefined
```


```
import { vi } from 'vitest'

const Mock = vi.fn()

// IntersectionObserver is "undefined" before calling "stubGlobal"

vi.stubGlobal('IntersectionObserver', Mock)

IntersectionObserver === Mock
global.IntersectionObserver === Mock
globalThis.IntersectionObserver === Mock
// if you are using jsdom or happy-dom
window.IntersectionObserver === Mock

vi.unstubAllGlobals()

globalThis.IntersectionObserver === undefined
'IntersectionObserver' in globalThis === false
// throws ReferenceError, because it's not defined
IntersectionObserver === undefined
```


vi.runAllTicks
--------------


* **Type:** `() => Vitest`


Calls every microtask that was queued by `process.nextTick`. This will also run all microtasks scheduled by themselves.


vi.runAllTimers
---------------


* **Type:** `() => Vitest`


This method will invoke every initiated timer until the timers queue is empty. It means that every timer called during `runAllTimers` will be fired. If you have an infinite interval, it will throw after 10 000 tries. For example this will log `1, 2, 3`:



ts
```
let i = 0
setTimeout(() => console.log(++i))
const interval = setInterval(() => {
  console.log(++i)
  if (i === 3)
    clearInterval(interval)

}, 50)

vi.runAllTimers()
```


```
let i = 0
setTimeout(() => console.log(++i))
const interval = setInterval(() => {
  console.log(++i)
  if (i === 3)
    clearInterval(interval)

}, 50)

vi.runAllTimers()
```


### vi.runAllTimersAsync


* **Type:** `() => Promise<Vitest>`


This method will asynchronously invoke every initiated timer until the timers queue is empty. It means that every timer called during `runAllTimersAsync` will be fired even asynchronous timers. If you have an infinite interval, it will throw after 10 000 tries. For example this will log `result`:



ts
```
setTimeout(async () => {
  console.log(await Promise.resolve('result'))
}, 100)

await vi.runAllTimersAsync()
```


```
setTimeout(async () => {
  console.log(await Promise.resolve('result'))
}, 100)

await vi.runAllTimersAsync()
```


vi.runOnlyPendingTimers
-----------------------


* **Type:** `() => Vitest`


This method will call every timer that was initiated after `vi.useFakeTimers()` call. It will not fire any timer that was initiated during its call. For example this will only log `1`:



ts
```
let i = 0
setInterval(() => console.log(++i), 50)

vi.runOnlyPendingTimers()
```


```
let i = 0
setInterval(() => console.log(++i), 50)

vi.runOnlyPendingTimers()
```


### vi.runOnlyPendingTimersAsync


* **Type:** `() => Promise<Vitest>`


This method will asynchronously call every timer that was initiated after `vi.useFakeTimers()` call, even asynchronous ones. It will not fire any timer that was initiated during its call. For example this will log `2, 3, 3, 1`:



ts
```
setTimeout(() => {
  console.log(1)
}, 100)
setTimeout(() => {
  Promise.resolve().then(() => {
    console.log(2)
    setInterval(() => {
      console.log(3)
    }, 40)
  })
}, 10)

await vi.runOnlyPendingTimersAsync()
```


```
setTimeout(() => {
  console.log(1)
}, 100)
setTimeout(() => {
  Promise.resolve().then(() => {
    console.log(2)
    setInterval(() => {
      console.log(3)
    }, 40)
  })
}, 10)

await vi.runOnlyPendingTimersAsync()
```


vi.setSystemTime
----------------


* **Type**: `(date: string | number | Date) => void`


Sets current date to the one that was passed. All `Date` calls will return this date.


Useful if you need to test anything that depends on the current date - for example [luxon](https://github.com/moment/luxon/) calls inside your code.



ts
```
const date = new Date(1998, 11, 19)

vi.useFakeTimers()
vi.setSystemTime(date)

expect(Date.now()).toBe(date.valueOf())

vi.useRealTimers()
```


```
const date = new Date(1998, 11, 19)

vi.useFakeTimers()
vi.setSystemTime(date)

expect(Date.now()).toBe(date.valueOf())

vi.useRealTimers()
```


vi.setConfig
------------


* **Type**: `RuntimeConfig`


Updates config for the current test file. You can only affect values that are used, when executing tests.


vi.spyOn
--------


* **Type:** `<T, K extends keyof T>(object: T, method: K, accessType?: 'get' | 'set') => MockInstance`


Creates a spy on a method or getter/setter of an object.



ts
```
let apples = 0
const cart = {
  getApples: () => 13,
}

const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples)
apples = 1

expect(cart.getApples()).toBe(1)

expect(spy).toHaveBeenCalled()
expect(spy).toHaveReturnedWith(1)
```


```
let apples = 0
const cart = {
  getApples: () => 13,
}

const spy = vi.spyOn(cart, 'getApples').mockImplementation(() => apples)
apples = 1

expect(cart.getApples()).toBe(1)

expect(spy).toHaveBeenCalled()
expect(spy).toHaveReturnedWith(1)
```


vi.stubGlobal
-------------


* **Type**: `(key: keyof globalThis & Window, value: any) => Vitest`


Puts a value on global variable. If you are using `jsdom` or `happy-dom`, also puts the value on `window` object.


Read more in ["Mocking Globals" section](../guide/mocking#globals).


vi.unmock
---------


* **Type**: `(path: string) => void`


Removes module from the mocked registry. All calls to import will return the original module even if it was mocked before. This call is hoisted (moved) to the top of the file, so it will only unmock modules that were defined in `setupFiles`, for example.


vi.doUnmock
-----------


* **Type**: `(path: string) => void`


The same as [`vi.unmock`](#vi-unmock), but is not hoisted to the top of the file. The next import of the module will import the original module instead of the mock. This will not unmock previously imported modules.



ts
```
// ./increment.js
export function increment(number) {
  return number + 1
}
```


```
// ./increment.js
export function increment(number) {
  return number + 1
}
```



ts
```
import { increment } from './increment.js'

// increment is already mocked, because vi.mock is hoisted
increment(1) === 100

// this is hoisted, and factory is called before the import on line 1
vi.mock('./increment.js', () => ({ increment: () => 100 }))

// all calls are mocked, and `increment` always returns 100
increment(1) === 100
increment(30) === 100

// this is not hoisted, so other import will return unmocked module
vi.doUnmock('./increment.js')

// this STILL returns 100, because `vi.doUnmock` doesn't reevaluate a module
increment(1) === 100
increment(30) === 100

// the next import is unmocked, now `increment` is the original function that returns count + 1
const { increment: unmockedIncrement } = await import('./increment.js')

unmockedIncrement(1) === 2
unmockedIncrement(30) === 31
```


```
import { increment } from './increment.js'

// increment is already mocked, because vi.mock is hoisted
increment(1) === 100

// this is hoisted, and factory is called before the import on line 1
vi.mock('./increment.js', () => ({ increment: () => 100 }))

// all calls are mocked, and `increment` always returns 100
increment(1) === 100
increment(30) === 100

// this is not hoisted, so other import will return unmocked module
vi.doUnmock('./increment.js')

// this STILL returns 100, because `vi.doUnmock` doesn't reevaluate a module
increment(1) === 100
increment(30) === 100

// the next import is unmocked, now `increment` is the original function that returns count + 1
const { increment: unmockedIncrement } = await import('./increment.js')

unmockedIncrement(1) === 2
unmockedIncrement(30) === 31
```


vi.useFakeTimers
----------------


* **Type:** `() => Vitest`


To enable mocking timers, you need to call this method. It will wrap all further calls to timers (such as `setTimeout`, `setInterval`, `clearTimeout`, `clearInterval`, `nextTick`, `setImmediate`, `clearImmediate`, and `Date`), until [`vi.useRealTimers()`](#vi-userealtimers) is called.


The implementation is based internally on [`@sinonjs/fake-timers`](https://github.com/sinonjs/fake-timers).


vi.useRealTimers
----------------


* **Type:** `() => Vitest`


When timers are run out, you may call this method to return mocked timers to its original implementations. All timers that were run before will not be restored.



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/api/vi.html>

expect
======


The following types are used in the type signatures below



ts
```
type Awaitable<T> = T | PromiseLike<T>
```


```
type Awaitable<T> = T | PromiseLike<T>
```


`expect` is used to create assertions. In this context `assertions` are functions that can be called to assert a statement. Vitest provides `chai` assertions by default and also `Jest` compatible assertions build on top of `chai`.


For example, this code asserts that an `input` value is equal to `2`. If it's not, the assertion will throw an error, and the test will fail.



ts
```
import { expect } from 'vitest'

const input = Math.sqrt(4)

expect(input).to.equal(2) // chai API
expect(input).toBe(2) // jest API
```


```
import { expect } from 'vitest'

const input = Math.sqrt(4)

expect(input).to.equal(2) // chai API
expect(input).toBe(2) // jest API
```


Technically this example doesn't use [`test`](index#test) function, so in the console you will see Nodejs error instead of Vitest output. To learn more about `test`, please read [Test API Reference](index).


Also, `expect` can be used statically to access matchers functions, described later, and more.



**WARNING**`expect` has no effect on testing types, if the expression doesn't have a type error. If you want to use Vitest as [type checker](../guide/testing-types), use [`expectTypeOf`](expect-typeof) or [`assertType`](assert-type).



soft
----


* **Type:** `ExpectStatic & (actual: any) => Assertions`


`expect.soft` functions similarly to `expect`, but instead of terminating the test execution upon a failed assertion, it continues running and marks the failure as a test failure. All errors encountered during the test will be displayed until the test is completed.



ts
```
import { expect, test } from 'vitest'

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3) // mark the test as fail and continue
  expect.soft(1 + 2).toBe(4) // mark the test as fail and continue
})
// At the end of the test, the above errors will be output.
```


```
import { expect, test } from 'vitest'

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3) // mark the test as fail and continue
  expect.soft(1 + 2).toBe(4) // mark the test as fail and continue
})
// At the end of the test, the above errors will be output.
```


It can also be used with `expect`. if `expect` assertion fails, the test will be terminated and all errors will be displayed.



ts
```
import { expect, test } from 'vitest'

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3) // mark the test as fail and continue
  expect(1 + 2).toBe(3) // failed and terminate the test, all previous errors will be output
  expect.soft(1 + 2).toBe(4) // do not run
})
```


```
import { expect, test } from 'vitest'

test('expect.soft test', () => {
  expect.soft(1 + 1).toBe(3) // mark the test as fail and continue
  expect(1 + 2).toBe(3) // failed and terminate the test, all previous errors will be output
  expect.soft(1 + 2).toBe(4) // do not run
})
```



**WARNING**`expect.soft` can only be used inside the [`test`](index#test) function.



not
---


Using `not` will negate the assertion. For example, this code asserts that an `input` value is not equal to `2`. If it's equal, the assertion will throw an error, and the test will fail.



ts
```
import { expect, test } from 'vitest'

const input = Math.sqrt(16)

expect(input).not.to.equal(2) // chai API
expect(input).not.toBe(2) // jest API
```


```
import { expect, test } from 'vitest'

const input = Math.sqrt(16)

expect(input).not.to.equal(2) // chai API
expect(input).not.toBe(2) // jest API
```


toBe
----


* **Type:** `(value: any) => Awaitable<void>`


`toBe` can be used to assert if primitives are equal or that objects share the same reference. It is equivalent of calling `expect(Object.is(3, 3)).toBe(true)`. If the objects are not the same, but you want to check if their structures are identical, you can use [`toEqual`](#toequal).


For example, the code below checks if the trader has 13 apples.



ts
```
import { expect, test } from 'vitest'

const stock = {
  type: 'apples',
  count: 13,
}

test('stock has 13 apples', () => {
  expect(stock.type).toBe('apples')
  expect(stock.count).toBe(13)
})

test('stocks are the same', () => {
  const refStock = stock // same reference

  expect(stock).toBe(refStock)
})
```


```
import { expect, test } from 'vitest'

const stock = {
  type: 'apples',
  count: 13,
}

test('stock has 13 apples', () => {
  expect(stock.type).toBe('apples')
  expect(stock.count).toBe(13)
})

test('stocks are the same', () => {
  const refStock = stock // same reference

  expect(stock).toBe(refStock)
})
```


Try not to use `toBe` with floating-point numbers. Since JavaScript rounds them, `0.1 + 0.2` is not strictly `0.3`. To reliably assert floating-point numbers, use [`toBeCloseTo`](#tobecloseto) assertion.


toBeCloseTo
-----------


* **Type:** `(value: number, numDigits?: number) => Awaitable<void>`


Use `toBeCloseTo` to compare floating-point numbers. The optional `numDigits` argument limits the number of digits to check *after* the decimal point. For example:



ts
```
import { expect, test } from 'vitest'

test.fails('decimals are not equal in javascript', () => {
  expect(0.2 + 0.1).toBe(0.3) // 0.2 + 0.1 is 0.30000000000000004
})

test('decimals are rounded to 5 after the point', () => {
  // 0.2 + 0.1 is 0.30000 | "000000000004" removed
  expect(0.2 + 0.1).toBeCloseTo(0.3, 5)
  // nothing from 0.30000000000000004 is removed
  expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50)
})
```


```
import { expect, test } from 'vitest'

test.fails('decimals are not equal in javascript', () => {
  expect(0.2 + 0.1).toBe(0.3) // 0.2 + 0.1 is 0.30000000000000004
})

test('decimals are rounded to 5 after the point', () => {
  // 0.2 + 0.1 is 0.30000 | "000000000004" removed
  expect(0.2 + 0.1).toBeCloseTo(0.3, 5)
  // nothing from 0.30000000000000004 is removed
  expect(0.2 + 0.1).not.toBeCloseTo(0.3, 50)
})
```


toBeDefined
-----------


* **Type:** `() => Awaitable<void>`


`toBeDefined` asserts that the value is not equal to `undefined`. Useful use case would be to check if function *returned* anything.



ts
```
import { expect, test } from 'vitest'

function getApples() {
  return 3
}

test('function returned something', () => {
  expect(getApples()).toBeDefined()
})
```


```
import { expect, test } from 'vitest'

function getApples() {
  return 3
}

test('function returned something', () => {
  expect(getApples()).toBeDefined()
})
```


toBeUndefined
-------------


* **Type:** `() => Awaitable<void>`


Opposite of `toBeDefined`, `toBeUndefined` asserts that the value *is* equal to `undefined`. Useful use case would be to check if function hasn't *returned* anything.



ts
```
import { expect, test } from 'vitest'

function getApplesFromStock(stock) {
  if (stock === 'Bill')
    return 13
}

test('mary doesn\'t have a stock', () => {
  expect(getApplesFromStock('Mary')).toBeUndefined()
})
```


```
import { expect, test } from 'vitest'

function getApplesFromStock(stock) {
  if (stock === 'Bill')
    return 13
}

test('mary doesn\'t have a stock', () => {
  expect(getApplesFromStock('Mary')).toBeUndefined()
})
```


toBeTruthy
----------


* **Type:** `() => Awaitable<void>`


`toBeTruthy` asserts that the value is true when converted to boolean. Useful if you don't care for the value, but just want to know it can be converted to `true`.


For example, having this code you don't care for the return value of `stocks.getInfo` - it maybe a complex object, a string, or anything else. The code will still work.



ts
```
import { Stocks } from './stocks.js'

const stocks = new Stocks()
stocks.sync('Bill')
if (stocks.getInfo('Bill'))
  stocks.sell('apples', 'Bill')
```


```
import { Stocks } from './stocks.js'

const stocks = new Stocks()
stocks.sync('Bill')
if (stocks.getInfo('Bill'))
  stocks.sell('apples', 'Bill')
```


So if you want to test that `stocks.getInfo` will be truthy, you could write:



ts
```
import { expect, test } from 'vitest'
import { Stocks } from './stocks.js'

const stocks = new Stocks()

test('if we know Bill stock, sell apples to him', () => {
  stocks.sync('Bill')
  expect(stocks.getInfo('Bill')).toBeTruthy()
})
```


```
import { expect, test } from 'vitest'
import { Stocks } from './stocks.js'

const stocks = new Stocks()

test('if we know Bill stock, sell apples to him', () => {
  stocks.sync('Bill')
  expect(stocks.getInfo('Bill')).toBeTruthy()
})
```


Everything in JavaScript is truthy, except `false`, `0`, `''`, `null`, `undefined`, and `NaN`.


toBeFalsy
---------


* **Type:** `() => Awaitable<void>`


`toBeFalsy` asserts that the value is false when converted to boolean. Useful if you don't care for the value, but just want to know if it can be converted to `false`.


For example, having this code you don't care for the return value of `stocks.stockFailed` - it may return any falsy value, but the code will still work.



ts
```
import { Stocks } from './stocks.js'

const stocks = new Stocks()
stocks.sync('Bill')
if (!stocks.stockFailed('Bill'))
  stocks.sell('apples', 'Bill')
```


```
import { Stocks } from './stocks.js'

const stocks = new Stocks()
stocks.sync('Bill')
if (!stocks.stockFailed('Bill'))
  stocks.sell('apples', 'Bill')
```


So if you want to test that `stocks.stockFailed` will be falsy, you could write:



ts
```
import { expect, test } from 'vitest'
import { Stocks } from './stocks.js'

const stocks = new Stocks()

test('if Bill stock hasn\'t failed, sell apples to him', () => {
  stocks.syncStocks('Bill')
  expect(stocks.stockFailed('Bill')).toBeFalsy()
})
```


```
import { expect, test } from 'vitest'
import { Stocks } from './stocks.js'

const stocks = new Stocks()

test('if Bill stock hasn\'t failed, sell apples to him', () => {
  stocks.syncStocks('Bill')
  expect(stocks.stockFailed('Bill')).toBeFalsy()
})
```


Everything in JavaScript is truthy, except `false`, `0`, `''`, `null`, `undefined`, and `NaN`.


toBeNull
--------


* **Type:** `() => Awaitable<void>`


`toBeNull` simply asserts if something is `null`. Alias for `.toBe(null)`.



ts
```
import { expect, test } from 'vitest'

function apples() {
  return null
}

test('we don\'t have apples', () => {
  expect(apples()).toBeNull()
})
```


```
import { expect, test } from 'vitest'

function apples() {
  return null
}

test('we don\'t have apples', () => {
  expect(apples()).toBeNull()
})
```


toBeNaN
-------


* **Type:** `() => Awaitable<void>`


`toBeNaN` simply asserts if something is `NaN`. Alias for `.toBe(NaN)`.



ts
```
import { expect, test } from 'vitest'

let i = 0

function getApplesCount() {
  i++
  return i > 1 ? Number.NaN : i
}

test('getApplesCount has some unusual side effects...', () => {
  expect(getApplesCount()).not.toBeNaN()
  expect(getApplesCount()).toBeNaN()
})
```


```
import { expect, test } from 'vitest'

let i = 0

function getApplesCount() {
  i++
  return i > 1 ? Number.NaN : i
}

test('getApplesCount has some unusual side effects...', () => {
  expect(getApplesCount()).not.toBeNaN()
  expect(getApplesCount()).toBeNaN()
})
```


toBeTypeOf
----------


* **Type:** `(c: 'bigint' | 'boolean' | 'function' | 'number' | 'object' | 'string' | 'symbol' | 'undefined') => Awaitable<void>`


`toBeTypeOf` asserts if an actual value is of type of received type.



ts
```
import { expect, test } from 'vitest'

const actual = 'stock'

test('stock is type of string', () => {
  expect(actual).toBeTypeOf('string')
})
```


```
import { expect, test } from 'vitest'

const actual = 'stock'

test('stock is type of string', () => {
  expect(actual).toBeTypeOf('string')
})
```


toBeInstanceOf
--------------


* **Type:** `(c: any) => Awaitable<void>`


`toBeInstanceOf` asserts if an actual value is instance of received class.



ts
```
import { expect, test } from 'vitest'
import { Stocks } from './stocks.js'

const stocks = new Stocks()

test('stocks are instance of Stocks', () => {
  expect(stocks).toBeInstanceOf(Stocks)
})
```


```
import { expect, test } from 'vitest'
import { Stocks } from './stocks.js'

const stocks = new Stocks()

test('stocks are instance of Stocks', () => {
  expect(stocks).toBeInstanceOf(Stocks)
})
```


toBeGreaterThan
---------------


* **Type:** `(n: number | bigint) => Awaitable<void>`


`toBeGreaterThan` asserts if actual value is greater than received one. Equal values will fail the test.



ts
```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have more then 10 apples', () => {
  expect(getApples()).toBeGreaterThan(10)
})
```


```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have more then 10 apples', () => {
  expect(getApples()).toBeGreaterThan(10)
})
```


toBeGreaterThanOrEqual
----------------------


* **Type:** `(n: number | bigint) => Awaitable<void>`


`toBeGreaterThanOrEqual` asserts if actual value is greater than received one or equal to it.



ts
```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have 11 apples or more', () => {
  expect(getApples()).toBeGreaterThanOrEqual(11)
})
```


```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have 11 apples or more', () => {
  expect(getApples()).toBeGreaterThanOrEqual(11)
})
```


toBeLessThan
------------


* **Type:** `(n: number | bigint) => Awaitable<void>`


`toBeLessThan` asserts if actual value is less than received one. Equal values will fail the test.



ts
```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have less then 20 apples', () => {
  expect(getApples()).toBeLessThan(20)
})
```


```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have less then 20 apples', () => {
  expect(getApples()).toBeLessThan(20)
})
```


toBeLessThanOrEqual
-------------------


* **Type:** `(n: number | bigint) => Awaitable<void>`


`toBeLessThanOrEqual` asserts if actual value is less than received one or equal to it.



ts
```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have 11 apples or less', () => {
  expect(getApples()).toBeLessThanOrEqual(11)
})
```


```
import { expect, test } from 'vitest'
import { getApples } from './stocks.js'

test('have 11 apples or less', () => {
  expect(getApples()).toBeLessThanOrEqual(11)
})
```


toEqual
-------


* **Type:** `(received: any) => Awaitable<void>`


`toEqual` asserts if actual value is equal to received one or has the same structure, if it is an object (compares them recursively). You can see the difference between `toEqual` and [`toBe`](#tobe) in this example:



ts
```
import { expect, test } from 'vitest'

const stockBill = {
  type: 'apples',
  count: 13,
}

const stockMary = {
  type: 'apples',
  count: 13,
}

test('stocks have the same properties', () => {
  expect(stockBill).toEqual(stockMary)
})

test('stocks are not the same', () => {
  expect(stockBill).not.toBe(stockMary)
})
```


```
import { expect, test } from 'vitest'

const stockBill = {
  type: 'apples',
  count: 13,
}

const stockMary = {
  type: 'apples',
  count: 13,
}

test('stocks have the same properties', () => {
  expect(stockBill).toEqual(stockMary)
})

test('stocks are not the same', () => {
  expect(stockBill).not.toBe(stockMary)
})
```



**WARNING**A *deep equality* will not be performed for `Error` objects. To test if something was thrown, use [`toThrowError`](#tothrowerror) assertion.


toStrictEqual
-------------


* **Type:** `(received: any) => Awaitable<void>`


`toStrictEqual` asserts if the actual value is equal to the received one or has the same structure if it is an object (compares them recursively), and of the same type.


Differences from [`.toEqual`](#toequal):


	+ Keys with `undefined` properties are checked. e.g. `{a: undefined, b: 2}` does not match `{b: 2}` when using `.toStrictEqual`.
	+ Array sparseness is checked. e.g. `[, 1]` does not match `[undefined, 1]` when using `.toStrictEqual`.
	+ Object types are checked to be equal. e.g. A class instance with fields `a` and `b` will not equal a literal object with fields `a` and `b`.
ts
```
import { expect, test } from 'vitest'

class Stock {
  constructor(type) {
    this.type = type
  }
}

test('structurally the same, but semantically different', () => {
  expect(new Stock('apples')).toEqual({ type: 'apples' })
  expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' })
})
```


```
import { expect, test } from 'vitest'

class Stock {
  constructor(type) {
    this.type = type
  }
}

test('structurally the same, but semantically different', () => {
  expect(new Stock('apples')).toEqual({ type: 'apples' })
  expect(new Stock('apples')).not.toStrictEqual({ type: 'apples' })
})
```


toContain
---------


* **Type:** `(received: string) => Awaitable<void>`


`toContain` asserts if the actual value is in an array. `toContain` can also check whether a string is a substring of another string.



ts
```
import { expect, test } from 'vitest'
import { getAllFruits } from './stocks.js'

test('the fruit list contains orange', () => {
  expect(getAllFruits()).toContain('orange')
})
```


```
import { expect, test } from 'vitest'
import { getAllFruits } from './stocks.js'

test('the fruit list contains orange', () => {
  expect(getAllFruits()).toContain('orange')
})
```


toContainEqual
--------------


* **Type:** `(received: any) => Awaitable<void>`


`toContainEqual` asserts if an item with a specific structure and values is contained in an array. It works like [`toEqual`](#toequal) inside for each element.



ts
```
import { expect, test } from 'vitest'
import { getFruitStock } from './stocks.js'

test('apple available', () => {
  expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 })
})
```


```
import { expect, test } from 'vitest'
import { getFruitStock } from './stocks.js'

test('apple available', () => {
  expect(getFruitStock()).toContainEqual({ fruit: 'apple', count: 5 })
})
```


toHaveLength
------------


* **Type:** `(received: number) => Awaitable<void>`


`toHaveLength` asserts if an object has a `.length` property and it is set to a certain numeric value.



ts
```
import { expect, test } from 'vitest'

test('toHaveLength', () => {
  expect('abc').toHaveLength(3)
  expect([1, 2, 3]).toHaveLength(3)

  expect('').not.toHaveLength(3) // doesn't have .length of 3
  expect({ length: 3 }).toHaveLength(3)
})
```


```
import { expect, test } from 'vitest'

test('toHaveLength', () => {
  expect('abc').toHaveLength(3)
  expect([1, 2, 3]).toHaveLength(3)

  expect('').not.toHaveLength(3) // doesn't have .length of 3
  expect({ length: 3 }).toHaveLength(3)
})
```


toHaveProperty
--------------


* **Type:** `(key: any, received?: any) => Awaitable<void>`


`toHaveProperty` asserts if a property at provided reference `key` exists for an object.


You can provide an optional value argument also known as deep equality, like the `toEqual` matcher to compare the received property value.



ts
```
import { expect, test } from 'vitest'

const invoice = {
  'isActive': true,
  'P.O': '12345',
  'customer': {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
  'total_amount': 5000,
  'items': [
    {
      type: 'apples',
      quantity: 10,
    },
    {
      type: 'oranges',
      quantity: 5,
    },
  ],
}

test('John Doe Invoice', () => {
  expect(invoice).toHaveProperty('isActive') // assert that the key exists
  expect(invoice).toHaveProperty('total_amount', 5000) // assert that the key exists and the value is equal

  expect(invoice).not.toHaveProperty('account') // assert that this key does not exist

  // Deep referencing using dot notation
  expect(invoice).toHaveProperty('customer.first_name')
  expect(invoice).toHaveProperty('customer.last_name', 'Doe')
  expect(invoice).not.toHaveProperty('customer.location', 'India')

  // Deep referencing using an array containing the key
  expect(invoice).toHaveProperty('items[0].type', 'apples')
  expect(invoice).toHaveProperty('items.0.type', 'apples') // dot notation also works

  // Deep referencing using an array containing the keyPath
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples')
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples') // string notation also works

  // Wrap your key in an array to avoid the key from being parsed as a deep reference
  expect(invoice).toHaveProperty(['P.O'], '12345')
})
```


```
import { expect, test } from 'vitest'

const invoice = {
  'isActive': true,
  'P.O': '12345',
  'customer': {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
  'total_amount': 5000,
  'items': [
    {
      type: 'apples',
      quantity: 10,
    },
    {
      type: 'oranges',
      quantity: 5,
    },
  ],
}

test('John Doe Invoice', () => {
  expect(invoice).toHaveProperty('isActive') // assert that the key exists
  expect(invoice).toHaveProperty('total_amount', 5000) // assert that the key exists and the value is equal

  expect(invoice).not.toHaveProperty('account') // assert that this key does not exist

  // Deep referencing using dot notation
  expect(invoice).toHaveProperty('customer.first_name')
  expect(invoice).toHaveProperty('customer.last_name', 'Doe')
  expect(invoice).not.toHaveProperty('customer.location', 'India')

  // Deep referencing using an array containing the key
  expect(invoice).toHaveProperty('items[0].type', 'apples')
  expect(invoice).toHaveProperty('items.0.type', 'apples') // dot notation also works

  // Deep referencing using an array containing the keyPath
  expect(invoice).toHaveProperty(['items', 0, 'type'], 'apples')
  expect(invoice).toHaveProperty(['items', '0', 'type'], 'apples') // string notation also works

  // Wrap your key in an array to avoid the key from being parsed as a deep reference
  expect(invoice).toHaveProperty(['P.O'], '12345')
})
```


toMatch
-------


* **Type:** `(received: string | regexp) => Awaitable<void>`


`toMatch` asserts if a string matches a regular expression or a string.



ts
```
import { expect, test } from 'vitest'

test('top fruits', () => {
  expect('top fruits include apple, orange and grape').toMatch(/apple/)
  expect('applefruits').toMatch('fruit') // toMatch also accepts a string
})
```


```
import { expect, test } from 'vitest'

test('top fruits', () => {
  expect('top fruits include apple, orange and grape').toMatch(/apple/)
  expect('applefruits').toMatch('fruit') // toMatch also accepts a string
})
```



**TIP**If the value in the error message is too truncated, you can increase [chaiConfig.truncateThreshold](../config/index#chaiconfig-truncatethreshold) in your config file.



toMatchObject
-------------


* **Type:** `(received: object | array) => Awaitable<void>`


`toMatchObject` asserts if an object matches a subset of the properties of an object.


You can also pass an array of objects. This is useful if you want to check that two arrays match in their number of elements, as opposed to `arrayContaining`, which allows for extra elements in the received array.



ts
```
import { expect, test } from 'vitest'

const johnInvoice = {
  isActive: true,
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
  total_amount: 5000,
  items: [
    {
      type: 'apples',
      quantity: 10,
    },
    {
      type: 'oranges',
      quantity: 5,
    },
  ],
}

const johnDetails = {
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
}

test('invoice has john personal details', () => {
  expect(johnInvoice).toMatchObject(johnDetails)
})

test('the number of elements must match exactly', () => {
  // Assert that an array of object matches
  expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
    { foo: 'bar' },
    { baz: 1 },
  ])
})
```


```
import { expect, test } from 'vitest'

const johnInvoice = {
  isActive: true,
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
  total_amount: 5000,
  items: [
    {
      type: 'apples',
      quantity: 10,
    },
    {
      type: 'oranges',
      quantity: 5,
    },
  ],
}

const johnDetails = {
  customer: {
    first_name: 'John',
    last_name: 'Doe',
    location: 'China',
  },
}

test('invoice has john personal details', () => {
  expect(johnInvoice).toMatchObject(johnDetails)
})

test('the number of elements must match exactly', () => {
  // Assert that an array of object matches
  expect([{ foo: 'bar' }, { baz: 1 }]).toMatchObject([
    { foo: 'bar' },
    { baz: 1 },
  ])
})
```


toThrowError
------------


* **Type:** `(received: any) => Awaitable<void>`
* **Alias:** `toThrow`


`toThrowError` asserts if a function throws an error when it is called.


You can provide an optional argument to test that a specific error is thrown:


	+ regular expression: error message matches the pattern
	+ string: error message includes the substring
**TIP**You must wrap the code in a function, otherwise the error will not be caught, and test will fail.



For example, if we want to test that `getFruitStock('pineapples')` throws, we could write:



ts
```
import { expect, test } from 'vitest'

function getFruitStock(type) {
  if (type === 'pineapples')
    throw new DiabetesError('Pineapples are not good for people with diabetes')

  // Do some other stuff
}

test('throws on pineapples', () => {
  // Test that the error message says "diabetes" somewhere: these are equivalent
  expect(() => getFruitStock('pineapples')).toThrowError(/diabetes/)
  expect(() => getFruitStock('pineapples')).toThrowError('diabetes')

  // Test the exact error message
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Pineapples are not good for people with diabetes$/,
  )
})
```


```
import { expect, test } from 'vitest'

function getFruitStock(type) {
  if (type === 'pineapples')
    throw new DiabetesError('Pineapples are not good for people with diabetes')

  // Do some other stuff
}

test('throws on pineapples', () => {
  // Test that the error message says "diabetes" somewhere: these are equivalent
  expect(() => getFruitStock('pineapples')).toThrowError(/diabetes/)
  expect(() => getFruitStock('pineapples')).toThrowError('diabetes')

  // Test the exact error message
  expect(() => getFruitStock('pineapples')).toThrowError(
    /^Pineapples are not good for people with diabetes$/,
  )
})
```



**TIP**To test async functions, use in combination with [rejects](#rejects).



js
```
function getAsyncFruitStock() {
  return Promise.reject(new Error('empty'))
}

test('throws on pineapples', async () => {
  await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty')
})
```


```
function getAsyncFruitStock() {
  return Promise.reject(new Error('empty'))
}

test('throws on pineapples', async () => {
  await expect(() => getAsyncFruitStock()).rejects.toThrowError('empty')
})
```


toMatchSnapshot
---------------


* **Type:** `<T>(shape?: Partial<T> | string, message?: string) => void`


This ensures that a value matches the most recent snapshot.


You can provide an optional `hint` string argument that is appended to the test name. Although Vitest always appends a number at the end of a snapshot name, short descriptive hints might be more useful than numbers to differentiate multiple snapshots in a single it or test block. Vitest sorts snapshots by name in the corresponding `.snap` file.



**TIP**When snapshot mismatch and causing the test failing, if the mismatch is expected, you can press `u` key to update the snapshot for once. Or you can pass `-u` or `--update` CLI options to make Vitest always update the tests.




ts
```
import { expect, test } from 'vitest'

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  expect(data).toMatchSnapshot()
})
```


```
import { expect, test } from 'vitest'

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  expect(data).toMatchSnapshot()
})
```


You can also provide a shape of an object, if you are testing just a shape of an object, and don't need it to be 100% compatible:



ts
```
import { expect, test } from 'vitest'

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  expect(data).toMatchSnapshot({ foo: expect.any(Set) })
})
```


```
import { expect, test } from 'vitest'

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  expect(data).toMatchSnapshot({ foo: expect.any(Set) })
})
```


toMatchInlineSnapshot
---------------------


* **Type:** `<T>(shape?: Partial<T> | string, snapshot?: string, message?: string) => void`


This ensures that a value matches the most recent snapshot.


Vitest adds and updates the inlineSnapshot string argument to the matcher in the test file (instead of an external `.snap` file).



ts
```
import { expect, test } from 'vitest'

test('matches inline snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  // Vitest will update following content when updating the snapshot
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `)
})
```


```
import { expect, test } from 'vitest'

test('matches inline snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  // Vitest will update following content when updating the snapshot
  expect(data).toMatchInlineSnapshot(`
    {
      "foo": Set {
        "bar",
        "snapshot",
      },
    }
  `)
})
```


You can also provide a shape of an object, if you are testing just a shape of an object, and don't need it to be 100% compatible:



ts
```
import { expect, test } from 'vitest'

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  expect(data).toMatchInlineSnapshot(
    { foo: expect.any(Set) },
    `
    {
      "foo": Any<Set>,
    }
  `
  )
})
```


```
import { expect, test } from 'vitest'

test('matches snapshot', () => {
  const data = { foo: new Set(['bar', 'snapshot']) }
  expect(data).toMatchInlineSnapshot(
    { foo: expect.any(Set) },
    `
    {
      "foo": Any<Set>,
    }
  `
  )
})
```


toMatchFileSnapshot
-------------------


* **Type:** `<T>(filepath: string, message?: string) => Promise<void>`
* **Version:** Since Vitest 0.30.0


Compare or update the snapshot with the content of a file explicitly specified (instead of the `.snap` file).



ts
```
import { expect, it } from 'vitest'

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }))
  await expect(result).toMatchFileSnapshot('./test/basic.output.html')
})
```


```
import { expect, it } from 'vitest'

it('render basic', async () => {
  const result = renderHTML(h('div', { class: 'foo' }))
  await expect(result).toMatchFileSnapshot('./test/basic.output.html')
})
```


Note that since file system operation is async, you need to use `await` with `toMatchFileSnapshot()`.


toThrowErrorMatchingSnapshot
----------------------------


* **Type:** `(message?: string) => void`


The same as [`toMatchSnapshot`](#tomatchsnapshot), but expects the same value as [`toThrowError`](#tothrowerror).


If the function throws an `Error`, the snapshot will be the error message. Otherwise, snapshot will be the value thrown by the function.


toThrowErrorMatchingInlineSnapshot
----------------------------------


* **Type:** `(snapshot?: string, message?: string) => void`


The same as [`toMatchInlineSnapshot`](#tomatchinlinesnapshot), but expects the same value as [`toThrowError`](#tothrowerror).


If the function throws an `Error`, the snapshot will be the error message. Otherwise, snapshot will be the value thrown by the function.


toHaveBeenCalled
----------------


* **Type:** `() => Awaitable<void>`


This assertion is useful for testing that a function has been called. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy')

  expect(buySpy).not.toHaveBeenCalled()

  market.buy('apples', 10)

  expect(buySpy).toHaveBeenCalled()
})
```


```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy')

  expect(buySpy).not.toHaveBeenCalled()

  market.buy('apples', 10)

  expect(buySpy).toHaveBeenCalled()
})
```


toHaveBeenCalledTimes
---------------------


* **Type**: `(amount: number) => Awaitable<void>`


This assertion checks if a function was called a certain amount of times. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function called two times', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).toHaveBeenCalledTimes(2)
})
```


```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function called two times', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).toHaveBeenCalledTimes(2)
})
```


toHaveBeenCalledWith
--------------------


* **Type**: `(...args: any[]) => Awaitable<void>`


This assertion checks if a function was called at least once with certain parameters. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).toHaveBeenCalledWith('apples', 10)
  expect(buySpy).toHaveBeenCalledWith('apples', 20)
})
```


```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).toHaveBeenCalledWith('apples', 10)
  expect(buySpy).toHaveBeenCalledWith('apples', 20)
})
```


toHaveBeenLastCalledWith
------------------------


* **Type**: `(...args: any[]) => Awaitable<void>`


This assertion checks if a function was called with certain parameters at it's last invocation. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).not.toHaveBeenLastCalledWith('apples', 10)
  expect(buySpy).toHaveBeenLastCalledWith('apples', 20)
})
```


```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('spy function', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).not.toHaveBeenLastCalledWith('apples', 10)
  expect(buySpy).toHaveBeenLastCalledWith('apples', 20)
})
```


toHaveBeenNthCalledWith
-----------------------


* **Type**: `(time: number, ...args: any[]) => Awaitable<void>`


This assertion checks if a function was called with certain parameters at the certain time. The count starts at 1. So, to check the second entry, you would write `.toHaveBeenNthCalledWith(2, ...)`.


Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('first call of spy function called with right params', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).toHaveBeenNthCalledWith(1, 'apples', 10)
})
```


```
import { expect, test, vi } from 'vitest'

const market = {
  buy(subject: string, amount: number) {
    // ...
  },
}

test('first call of spy function called with right params', () => {
  const buySpy = vi.spyOn(market, 'buy')

  market.buy('apples', 10)
  market.buy('apples', 20)

  expect(buySpy).toHaveBeenNthCalledWith(1, 'apples', 10)
})
```


toHaveReturned
--------------


* **Type**: `() => Awaitable<void>`


This assertion checks if a function has successfully returned a value at least once (i.e., did not throw an error). Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

function getApplesPrice(amount: number) {
  const PRICE = 10
  return amount * PRICE
}

test('spy function returned a value', () => {
  const getPriceSpy = vi.fn(getApplesPrice)

  const price = getPriceSpy(10)

  expect(price).toBe(100)
  expect(getPriceSpy).toHaveReturned()
})
```


```
import { expect, test, vi } from 'vitest'

function getApplesPrice(amount: number) {
  const PRICE = 10
  return amount * PRICE
}

test('spy function returned a value', () => {
  const getPriceSpy = vi.fn(getApplesPrice)

  const price = getPriceSpy(10)

  expect(price).toBe(100)
  expect(getPriceSpy).toHaveReturned()
})
```


toHaveReturnedTimes
-------------------


* **Type**: `(amount: number) => Awaitable<void>`


This assertion checks if a function has successfully returned a value exact amount of times (i.e., did not throw an error). Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

test('spy function returns a value two times', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')
  sell('bananas')

  expect(sell).toHaveReturnedTimes(2)
})
```


```
import { expect, test, vi } from 'vitest'

test('spy function returns a value two times', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')
  sell('bananas')

  expect(sell).toHaveReturnedTimes(2)
})
```


toHaveReturnedWith
------------------


* **Type**: `(returnValue: any) => Awaitable<void>`


You can call this assertion to check if a function has successfully returned a value with certain parameters at least once. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

test('spy function returns a product', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')

  expect(sell).toHaveReturnedWith({ product: 'apples' })
})
```


```
import { expect, test, vi } from 'vitest'

test('spy function returns a product', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')

  expect(sell).toHaveReturnedWith({ product: 'apples' })
})
```


toHaveLastReturnedWith
----------------------


* **Type**: `(returnValue: any) => Awaitable<void>`


You can call this assertion to check if a function has successfully returned a value with certain parameters on it's last invoking. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

test('spy function returns bananas on a last call', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')
  sell('bananas')

  expect(sell).toHaveLastReturnedWith({ product: 'bananas' })
})
```


```
import { expect, test, vi } from 'vitest'

test('spy function returns bananas on a last call', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')
  sell('bananas')

  expect(sell).toHaveLastReturnedWith({ product: 'bananas' })
})
```


toHaveNthReturnedWith
---------------------


* **Type**: `(time: number, returnValue: any) => Awaitable<void>`


You can call this assertion to check if a function has successfully returned a value with certain parameters on a certain call. Requires a spy function to be passed to `expect`.



ts
```
import { expect, test, vi } from 'vitest'

test('spy function returns bananas on second call', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')
  sell('bananas')

  expect(sell).toHaveNthReturnedWith(2, { product: 'bananas' })
})
```


```
import { expect, test, vi } from 'vitest'

test('spy function returns bananas on second call', () => {
  const sell = vi.fn((product: string) => ({ product }))

  sell('apples')
  sell('bananas')

  expect(sell).toHaveNthReturnedWith(2, { product: 'bananas' })
})
```


toSatisfy
---------


* **Type:** `(predicate: (value: any) => boolean) => Awaitable<void>`


This assertion checks if a value satisfies a certain predicate.



ts
```
describe('toSatisfy()', () => {
  const isOdd = (value: number) => value % 2 !== 0

  it('pass with 0', () => {
    expect(1).toSatisfy(isOdd)
  })

  it('pass with negotiation', () => {
    expect(2).not.toSatisfy(isOdd)
  })
})
```


```
describe('toSatisfy()', () => {
  const isOdd = (value: number) => value % 2 !== 0

  it('pass with 0', () => {
    expect(1).toSatisfy(isOdd)
  })

  it('pass with negotiation', () => {
    expect(2).not.toSatisfy(isOdd)
  })
})
```


resolves
--------


* **Type:** `Promisify<Assertions>`


`resolves` is intended to remove boilerplate when asserting asynchronous code. Use it to unwrap value from the pending promise and assert its value with usual assertions. If the promise rejects, the assertion will fail.


It returns the same `Assertions` object, but all matchers now return `Promise`, so you would need to `await` it. Also works with `chai` assertions.


For example, if you have a function, that makes an API call and returns some data, you may use this code to assert its return value:



ts
```
import { expect, test } from 'vitest'

async function buyApples() {
  return fetch('/buy/apples').then(r => r.json())
}

test('buyApples returns new stock id', async () => {
  // toEqual returns a promise now, so you HAVE to await it
  await expect(buyApples()).resolves.toEqual({ id: 1 }) // jest API
  await expect(buyApples()).resolves.to.equal({ id: 1 }) // chai API
})
```


```
import { expect, test } from 'vitest'

async function buyApples() {
  return fetch('/buy/apples').then(r => r.json())
}

test('buyApples returns new stock id', async () => {
  // toEqual returns a promise now, so you HAVE to await it
  await expect(buyApples()).resolves.toEqual({ id: 1 }) // jest API
  await expect(buyApples()).resolves.to.equal({ id: 1 }) // chai API
})
```



**WARNING**If the assertion is not awaited, then you will have a false-positive test that will pass every time. To make sure that assertions are actually called, you may use [`expect.assertions(number)`](#expect-assertions).


rejects
-------


* **Type:** `Promisify<Assertions>`


`rejects` is intended to remove boilerplate when asserting asynchronous code. Use it to unwrap reason why the promise was rejected, and assert its value with usual assertions. If the promise successfully resolves, the assertion will fail.


It returns the same `Assertions` object, but all matchers now return `Promise`, so you would need to `await` it. Also works with `chai` assertions.


For example, if you have a function that fails when you call it, you may use this code to assert the reason:



ts
```
import { expect, test } from 'vitest'

async function buyApples(id) {
  if (!id)
    throw new Error('no id')
}

test('buyApples throws an error when no id provided', async () => {
  // toThrow returns a promise now, so you HAVE to await it
  await expect(buyApples()).rejects.toThrow('no id')
})
```


```
import { expect, test } from 'vitest'

async function buyApples(id) {
  if (!id)
    throw new Error('no id')
}

test('buyApples throws an error when no id provided', async () => {
  // toThrow returns a promise now, so you HAVE to await it
  await expect(buyApples()).rejects.toThrow('no id')
})
```



**WARNING**If the assertion is not awaited, then you will have a false-positive test that will pass every time. To make sure that assertions were actually called, you can use [`expect.assertions(number)`](#expect-assertions).


expect.assertions
-----------------


* **Type:** `(count: number) => void`


After the test has passed or failed verify that a certain number of assertions was called during a test. A useful case would be to check if an asynchronous code was called.


For example, if we have a function that asynchronously calls two matchers, we can assert that they were actually called.



ts
```
import { expect, test } from 'vitest'

async function doAsync(...cbs) {
  await Promise.all(
    cbs.map((cb, index) => cb({ index })),
  )
}

test('all assertions are called', async () => {
  expect.assertions(2)
  function callback1(data) {
    expect(data).toBeTruthy()
  }
  function callback2(data) {
    expect(data).toBeTruthy()
  }

  await doAsync(callback1, callback2)
})
```


```
import { expect, test } from 'vitest'

async function doAsync(...cbs) {
  await Promise.all(
    cbs.map((cb, index) => cb({ index })),
  )
}

test('all assertions are called', async () => {
  expect.assertions(2)
  function callback1(data) {
    expect(data).toBeTruthy()
  }
  function callback2(data) {
    expect(data).toBeTruthy()
  }

  await doAsync(callback1, callback2)
})
```



**WARNING**When using `assertions` with async concurrent tests, `expect` from the local [Test Context](../guide/test-context) must be used to ensure the right test is detected.


expect.hasAssertions
--------------------


* **Type:** `() => void`


After the test has passed or failed verify that at least one assertion was called during a test. A useful case would be to check if an asynchronous code was called.


For example, if you have a code that calls a callback, we can make an assertion inside a callback, but the test will always pass if we don't check if an assertion was called.



ts
```
import { expect, test } from 'vitest'
import { db } from './db.js'

const cbs = []

function onSelect(cb) {
  cbs.push(cb)
}

// after selecting from db, we call all callbacks
function select(id) {
  return db.select({ id }).then((data) => {
    return Promise.all(
      cbs.map(cb => cb(data)),
    )
  })
}

test('callback was called', async () => {
  expect.hasAssertions()
  onSelect((data) => {
    // should be called on select
    expect(data).toBeTruthy()
  })
  // if not awaited, test will fail
  // if you don't have expect.hasAssertions(), test will pass
  await select(3)
})
```


```
import { expect, test } from 'vitest'
import { db } from './db.js'

const cbs = []

function onSelect(cb) {
  cbs.push(cb)
}

// after selecting from db, we call all callbacks
function select(id) {
  return db.select({ id }).then((data) => {
    return Promise.all(
      cbs.map(cb => cb(data)),
    )
  })
}

test('callback was called', async () => {
  expect.hasAssertions()
  onSelect((data) => {
    // should be called on select
    expect(data).toBeTruthy()
  })
  // if not awaited, test will fail
  // if you don't have expect.hasAssertions(), test will pass
  await select(3)
})
```


expect.unreachable
------------------


* **Type:** `(message?: string) => never`


This method is used to asserting that a line should never be reached.


For example, if we want to test that `build()` throws due to receiving directories having no `src` folder, and also handle each error separately, we could do this:



ts
```
import { expect, test } from 'vitest'

async function build(dir) {
  if (dir.includes('no-src'))
    throw new Error(`${dir}/src does not exist`)
}

const errorDirs = [
  'no-src-folder',
  // ...
]

test.each(errorDirs)('build fails with "%s"', async (dir) => {
  try {
    await build(dir)
    expect.unreachable('Should not pass build')
  }
  catch (err: any) {
    expect(err).toBeInstanceOf(Error)
    expect(err.stack).toContain('build')

    switch (dir) {
      case 'no-src-folder':
        expect(err.message).toBe(`${dir}/src does not exist`)
        break
      default:
        // to exhaust all error tests
        expect.unreachable('All error test must be handled')
        break
    }
  }
})
```


```
import { expect, test } from 'vitest'

async function build(dir) {
  if (dir.includes('no-src'))
    throw new Error(`${dir}/src does not exist`)
}

const errorDirs = [
  'no-src-folder',
  // ...
]

test.each(errorDirs)('build fails with "%s"', async (dir) => {
  try {
    await build(dir)
    expect.unreachable('Should not pass build')
  }
  catch (err: any) {
    expect(err).toBeInstanceOf(Error)
    expect(err.stack).toContain('build')

    switch (dir) {
      case 'no-src-folder':
        expect(err.message).toBe(`${dir}/src does not exist`)
        break
      default:
        // to exhaust all error tests
        expect.unreachable('All error test must be handled')
        break
    }
  }
})
```


expect.anything
---------------


* **Type:** `() => any`


This asymmetric matcher, when used with equality check, will always return `true`. Useful, if you just want to be sure that the property exist.



ts
```
import { expect, test } from 'vitest'

test('object has "apples" key', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() })
})
```


```
import { expect, test } from 'vitest'

test('object has "apples" key', () => {
  expect({ apples: 22 }).toEqual({ apples: expect.anything() })
})
```


expect.any
----------


* **Type:** `(constructor: unknown) => any`


This asymmetric matcher, when used with an equality check, will return `true` only if the value is an instance of a specified constructor. Useful, if you have a value that is generated each time, and you only want to know that it exists with a proper type.



ts
```
import { expect, test } from 'vitest'
import { generateId } from './generators.js'

test('"id" is a number', () => {
  expect({ id: generateId() }).toEqual({ id: expect.any(Number) })
})
```


```
import { expect, test } from 'vitest'
import { generateId } from './generators.js'

test('"id" is a number', () => {
  expect({ id: generateId() }).toEqual({ id: expect.any(Number) })
})
```


expect.arrayContaining
----------------------


* **Type:** `<T>(expected: T[]) => any`


When used with an equality check, this asymmetric matcher will return `true` if the value is an array and contains specified items.



ts
```
import { expect, test } from 'vitest'

test('basket includes fuji', () => {
  const basket = {
    varieties: [
      'Empire',
      'Fuji',
      'Gala',
    ],
    count: 3
  }
  expect(basket).toEqual({
    count: 3,
    varieties: expect.arrayContaining(['Fuji'])
  })
})
```


```
import { expect, test } from 'vitest'

test('basket includes fuji', () => {
  const basket = {
    varieties: [
      'Empire',
      'Fuji',
      'Gala',
    ],
    count: 3
  }
  expect(basket).toEqual({
    count: 3,
    varieties: expect.arrayContaining(['Fuji'])
  })
})
```



**TIP**You can use `expect.not` with this matcher to negate the expected value.


expect.objectContaining
-----------------------


* **Type:** `(expected: any) => any`


When used with an equality check, this asymmetric matcher will return `true` if the value has a similar shape.



ts
```
import { expect, test } from 'vitest'

test('basket has empire apples', () => {
  const basket = {
    varieties: [
      {
        name: 'Empire',
        count: 1,
      }
    ],
  }
  expect(basket).toEqual({
    varieties: [
      expect.objectContaining({ name: 'Empire' }),
    ]
  })
})
```


```
import { expect, test } from 'vitest'

test('basket has empire apples', () => {
  const basket = {
    varieties: [
      {
        name: 'Empire',
        count: 1,
      }
    ],
  }
  expect(basket).toEqual({
    varieties: [
      expect.objectContaining({ name: 'Empire' }),
    ]
  })
})
```



**TIP**You can use `expect.not` with this matcher to negate the expected value.


expect.stringContaining
-----------------------


* **Type:** `(expected: any) => any`


When used with an equality check, this asymmetric matcher will return `true` if the value is a string and contains a specified substring.



ts
```
import { expect, test } from 'vitest'

test('variety has "Emp" in its name', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  }
  expect(variety).toEqual({
    name: expect.stringContaining('Emp'),
    count: 1,
  })
})
```


```
import { expect, test } from 'vitest'

test('variety has "Emp" in its name', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  }
  expect(variety).toEqual({
    name: expect.stringContaining('Emp'),
    count: 1,
  })
})
```



**TIP**You can use `expect.not` with this matcher to negate the expected value.


expect.stringMatching
---------------------


* **Type:** `(expected: any) => any`


When used with an equality check, this asymmetric matcher will return `true` if the value is a string and contains a specified substring or if the string matches a regular expression.



ts
```
import { expect, test } from 'vitest'

test('variety ends with "re"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  }
  expect(variety).toEqual({
    name: expect.stringMatching(/re$/),
    count: 1,
  })
})
```


```
import { expect, test } from 'vitest'

test('variety ends with "re"', () => {
  const variety = {
    name: 'Empire',
    count: 1,
  }
  expect(variety).toEqual({
    name: expect.stringMatching(/re$/),
    count: 1,
  })
})
```



**TIP**You can use `expect.not` with this matcher to negate the expected value.


expect.addSnapshotSerializer
----------------------------


* **Type:** `(plugin: PrettyFormatPlugin) => void`


This method adds custom serializers that are called when creating a snapshot. This is an advanced feature - if you want to know more, please read a [guide on custom serializers](../guide/snapshot#custom-serializer).


If you are adding custom serializers, you should call this method inside [`setupFiles`](../config/index#setupfiles). This will affect every snapshot.



**TIP**If you previously used Vue CLI with Jest, you might want to install [jest-serializer-vue](https://www.npmjs.com/package/jest-serializer-vue). Otherwise, your snapshots will be wrapped in a string, which cases `"` to be escaped.


expect.extend
-------------


* **Type:** `(matchers: MatchersObject) => void`


You can extend default matchers with your own. This function is used to extend the matchers object with custom matchers.


When you define matchers that way, you also create asymmetric matchers that can be used like `expect.stringContaining`.



ts
```
import { expect, test } from 'vitest'

test('custom matchers', () => {
  expect.extend({
    toBeFoo: (received, expected) => {
      if (received !== 'foo') {
        return {
          message: () => `expected ${received} to be foo`,
          pass: false,
        }
      }
    },
  })

  expect('foo').toBeFoo()
  expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() })
})
```


```
import { expect, test } from 'vitest'

test('custom matchers', () => {
  expect.extend({
    toBeFoo: (received, expected) => {
      if (received !== 'foo') {
        return {
          message: () => `expected ${received} to be foo`,
          pass: false,
        }
      }
    },
  })

  expect('foo').toBeFoo()
  expect({ foo: 'foo' }).toEqual({ foo: expect.toBeFoo() })
})
```



**TIP**If you want your matchers to appear in every test, you should call this method inside [`setupFiles`](../config/index#setupFiles).



This function is compatible with Jest's `expect.extend`, so any library that uses it to create custom matchers will work with Vitest.


If you are using TypeScript, since Vitest 0.31.0 you can extend default `Assertion` interface in an ambient declaration file (e.g: `vitest.d.ts`) with the code below:



ts
```
interface CustomMatchers<R = unknown> {
  toBeFoo(): R
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}
```


```
interface CustomMatchers<R = unknown> {
  toBeFoo(): R
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}
```



**WARNING**Don't forget to include the ambient declaration file in your `tsconfig.json`.




**TIP**If you want to know more, checkout [guide on extending matchers](../guide/extending-matchers).



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/api/expect.html>

expectTypeOf
============


* **Type:** `<T>(a: unknown) => ExpectTypeOf`


not
---


* **Type:** `ExpectTypeOf`


You can negate all assertions, using `.not` property.


toEqualTypeOf
-------------


* **Type:** `<T>(expected: T) => void`


This matcher will check if the types are fully equal to each other. This matcher will not fail if two objects have different values, but the same type. It will fail however if an object is missing a property.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>()
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 })
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 })
expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf({ a: 1 }).toEqualTypeOf<{ a: number }>()
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 1 })
expectTypeOf({ a: 1 }).toEqualTypeOf({ a: 2 })
expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>()
```


toMatchTypeOf
-------------


* **Type:** `<T>(expected: T) => void`


This matcher checks if expect type extends provided type. It is different from `toEqual` and is more similar to [expect's](expect) `toMatchObject()`. With this matcher, you can check if an object “matches” a type.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf({ a: 1 })
expectTypeOf<number>().toMatchTypeOf<string | number>()
expectTypeOf<string | number>().not.toMatchTypeOf<number>()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf({ a: 1, b: 1 }).toMatchTypeOf({ a: 1 })
expectTypeOf<number>().toMatchTypeOf<string | number>()
expectTypeOf<string | number>().not.toMatchTypeOf<number>()
```


extract
-------


* **Type:** `ExpectTypeOf<ExtractedUnion>`


You can use `.extract` to narrow down types for further testing.



ts
```
import { expectTypeOf } from 'vitest'

type ResponsiveProp<T> = T | T[] | { xs?: T; sm?: T; md?: T }

interface CSSProperties { margin?: string; padding?: string }

function getResponsiveProp<T>(_props: T): ResponsiveProp<T> {
  return {}
}

const cssProperties: CSSProperties = { margin: '1px', padding: '2px' }

expectTypeOf(getResponsiveProp(cssProperties))
  .extract<{ xs?: any }>() // extracts the last type from a union
  .toEqualTypeOf<{ xs?: CSSProperties; sm?: CSSProperties; md?: CSSProperties }>()

expectTypeOf(getResponsiveProp(cssProperties))
  .extract<unknown[]>() // extracts an array from a union
  .toEqualTypeOf<CSSProperties[]>()
```


```
import { expectTypeOf } from 'vitest'

type ResponsiveProp<T> = T | T[] | { xs?: T; sm?: T; md?: T }

interface CSSProperties { margin?: string; padding?: string }

function getResponsiveProp<T>(_props: T): ResponsiveProp<T> {
  return {}
}

const cssProperties: CSSProperties = { margin: '1px', padding: '2px' }

expectTypeOf(getResponsiveProp(cssProperties))
  .extract<{ xs?: any }>() // extracts the last type from a union
  .toEqualTypeOf<{ xs?: CSSProperties; sm?: CSSProperties; md?: CSSProperties }>()

expectTypeOf(getResponsiveProp(cssProperties))
  .extract<unknown[]>() // extracts an array from a union
  .toEqualTypeOf<CSSProperties[]>()
```



**WARNING**If no type is found in the union, `.extract` will return `never`.



exclude
-------


* **Type:** `ExpectTypeOf<NonExcludedUnion>`


You can use `.exclude` to remove types from a union for further testing.



ts
```
import { expectTypeOf } from 'vitest'

type ResponsiveProp<T> = T | T[] | { xs?: T; sm?: T; md?: T }

interface CSSProperties { margin?: string; padding?: string }

function getResponsiveProp<T>(_props: T): ResponsiveProp<T> {
  return {}
}

const cssProperties: CSSProperties = { margin: '1px', padding: '2px' }

expectTypeOf(getResponsiveProp(cssProperties))
  .exclude<unknown[]>()
  .exclude<{ xs?: unknown }>() // or just .exclude<unknown[] | { xs?: unknown }>()
  .toEqualTypeOf<CSSProperties>()
```


```
import { expectTypeOf } from 'vitest'

type ResponsiveProp<T> = T | T[] | { xs?: T; sm?: T; md?: T }

interface CSSProperties { margin?: string; padding?: string }

function getResponsiveProp<T>(_props: T): ResponsiveProp<T> {
  return {}
}

const cssProperties: CSSProperties = { margin: '1px', padding: '2px' }

expectTypeOf(getResponsiveProp(cssProperties))
  .exclude<unknown[]>()
  .exclude<{ xs?: unknown }>() // or just .exclude<unknown[] | { xs?: unknown }>()
  .toEqualTypeOf<CSSProperties>()
```



**WARNING**If no type is found in the union, `.exclude` will return `never`.



returns
-------


* **Type:** `ExpectTypeOf<ReturnValue>`


You can use `.returns` to extract return value of a function type.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(() => {}).returns.toBeVoid()
expectTypeOf((a: number) => [a, a]).returns.toEqualTypeOf([1, 2])
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(() => {}).returns.toBeVoid()
expectTypeOf((a: number) => [a, a]).returns.toEqualTypeOf([1, 2])
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.



parameters
----------


* **Type:** `ExpectTypeOf<Parameters>`


You can extract function arguments with `.parameters` to perform assertions on its value. Parameters are returned as an array.



ts
```
import { expectTypeOf } from 'vitest'

type NoParam = () => void
type HasParam = (s: string) => void

expectTypeOf<NoParam>().parameters.toEqualTypeOf<[]>()
expectTypeOf<HasParam>().parameters.toEqualTypeOf<[string]>()
```


```
import { expectTypeOf } from 'vitest'

type NoParam = () => void
type HasParam = (s: string) => void

expectTypeOf<NoParam>().parameters.toEqualTypeOf<[]>()
expectTypeOf<HasParam>().parameters.toEqualTypeOf<[string]>()
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.




**TIP**You can also use [`.toBeCallableWith`](#tobecallablewith) matcher as a more expressive assertion.



parameter
---------


* **Type:** `(nth: number) => ExpectTypeOf`


You can extract a certain function argument with `.parameter(number)` call to perform other assertions on it.



ts
```
import { expectTypeOf } from 'vitest'

function foo(a: number, b: string) {
  return [a, b]
}

expectTypeOf(foo).parameter(0).toBeNumber()
expectTypeOf(foo).parameter(1).toBeString()
```


```
import { expectTypeOf } from 'vitest'

function foo(a: number, b: string) {
  return [a, b]
}

expectTypeOf(foo).parameter(0).toBeNumber()
expectTypeOf(foo).parameter(1).toBeString()
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.



constructorParameters
---------------------


* **Type:** `ExpectTypeOf<ConstructorParameters>`


You can extract constructor parameters as an array of values and perform assertions on them with this method.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(Date).constructorParameters.toEqualTypeOf<[] | [string | number | Date]>()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(Date).constructorParameters.toEqualTypeOf<[] | [string | number | Date]>()
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.




**TIP**You can also use [`.toBeConstructibleWith`](#tobeconstructiblewith) matcher as a more expressive assertion.



instance
--------


* **Type:** `ExpectTypeOf<ConstructableInstance>`


This property gives access to matchers that can be performed on an instance of the provided class.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(Date).instance.toHaveProperty('toISOString')
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(Date).instance.toHaveProperty('toISOString')
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.



items
-----


* **Type:** `ExpectTypeOf<T>`


You can get array item type with `.items` to perform further assertions.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf([1, 2, 3]).items.toEqualTypeOf<number>()
expectTypeOf([1, 2, 3]).items.not.toEqualTypeOf<string>()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf([1, 2, 3]).items.toEqualTypeOf<number>()
expectTypeOf([1, 2, 3]).items.not.toEqualTypeOf<string>()
```


resolves
--------


* **Type:** `ExpectTypeOf<ResolvedPromise>`


This matcher extracts resolved value of a `Promise`, so you can perform other assertions on it.



ts
```
import { expectTypeOf } from 'vitest'

async function asyncFunc() {
  return 123
}

expectTypeOf(asyncFunc).returns.resolves.toBeNumber()
expectTypeOf(Promise.resolve('string')).resolves.toBeString()
```


```
import { expectTypeOf } from 'vitest'

async function asyncFunc() {
  return 123
}

expectTypeOf(asyncFunc).returns.resolves.toBeNumber()
expectTypeOf(Promise.resolve('string')).resolves.toBeString()
```



**WARNING**If used on a non-promise type, it will return `never`, so you won't be able to chain it with other matchers.



guards
------


* **Type:** `ExpectTypeOf<Guard>`


This matcher extracts guard value (e.g., `v is number`), so you can perform assertions on it.



ts
```
import { expectTypeOf } from 'vitest'

function isString(v: any): v is string {
  return typeof v === 'string'
}
expectTypeOf(isString).guards.toBeString()
```


```
import { expectTypeOf } from 'vitest'

function isString(v: any): v is string {
  return typeof v === 'string'
}
expectTypeOf(isString).guards.toBeString()
```



**WARNING**Returns `never`, if the value is not a guard function, so you won't be able to chain it with other matchers.



asserts
-------


* **Type:** `ExpectTypeOf<Assert>`


This matcher extracts assert value (e.g., `assert v is number`), so you can perform assertions on it.



ts
```
import { expectTypeOf } from 'vitest'

function assertNumber(v: any): asserts v is number {
  if (typeof v !== 'number')
    throw new TypeError('Nope !')
}

expectTypeOf(assertNumber).asserts.toBeNumber()
```


```
import { expectTypeOf } from 'vitest'

function assertNumber(v: any): asserts v is number {
  if (typeof v !== 'number')
    throw new TypeError('Nope !')
}

expectTypeOf(assertNumber).asserts.toBeNumber()
```



**WARNING**Returns `never`, if the value is not an assert function, so you won't be able to chain it with other matchers.



toBeAny
-------


* **Type:** `() => void`


With this matcher you can check, if provided type is `any` type. If the type is too specific, the test will fail.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf<any>().toBeAny()
expectTypeOf({} as any).toBeAny()
expectTypeOf('string').not.toBeAny()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf<any>().toBeAny()
expectTypeOf({} as any).toBeAny()
expectTypeOf('string').not.toBeAny()
```


toBeUnknown
-----------


* **Type:** `() => void`


This matcher checks, if provided type is `unknown` type.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf().toBeUnknown()
expectTypeOf({} as unknown).toBeUnknown()
expectTypeOf('string').not.toBeUnknown()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf().toBeUnknown()
expectTypeOf({} as unknown).toBeUnknown()
expectTypeOf('string').not.toBeUnknown()
```


toBeNever
---------


* **Type:** `() => void`


This matcher checks, if provided type is a `never` type.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf<never>().toBeNever()
expectTypeOf((): never => {}).returns.toBeNever()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf<never>().toBeNever()
expectTypeOf((): never => {}).returns.toBeNever()
```


toBeFunction
------------


* **Type:** `() => void`


This matcher checks, if provided type is a `function`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeFunction()
expectTypeOf((): never => {}).toBeFunction()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeFunction()
expectTypeOf((): never => {}).toBeFunction()
```


toBeObject
----------


* **Type:** `() => void`


This matcher checks, if provided type is an `object`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeObject()
expectTypeOf({}).toBeObject()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeObject()
expectTypeOf({}).toBeObject()
```


toBeArray
---------


* **Type:** `() => void`


This matcher checks, if provided type is `Array<T>`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeArray()
expectTypeOf([]).toBeArray()
expectTypeOf([1, 2]).toBeArray()
expectTypeOf([{}, 42]).toBeArray()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeArray()
expectTypeOf([]).toBeArray()
expectTypeOf([1, 2]).toBeArray()
expectTypeOf([{}, 42]).toBeArray()
```


toBeString
----------


* **Type:** `() => void`


This matcher checks, if provided type is a `string`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeString()
expectTypeOf('').toBeString()
expectTypeOf('a').toBeString()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeString()
expectTypeOf('').toBeString()
expectTypeOf('a').toBeString()
```


toBeBoolean
-----------


* **Type:** `() => void`


This matcher checks, if provided type is `boolean`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeBoolean()
expectTypeOf(true).toBeBoolean()
expectTypeOf<boolean>().toBeBoolean()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(42).not.toBeBoolean()
expectTypeOf(true).toBeBoolean()
expectTypeOf<boolean>().toBeBoolean()
```


toBeVoid
--------


* **Type:** `() => void`


This matcher checks, if provided type is `void`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(() => {}).returns.toBeVoid()
expectTypeOf<void>().toBeVoid()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(() => {}).returns.toBeVoid()
expectTypeOf<void>().toBeVoid()
```


toBeSymbol
----------


* **Type:** `() => void`


This matcher checks, if provided type is a `symbol`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(Symbol(1)).toBeSymbol()
expectTypeOf<symbol>().toBeSymbol()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(Symbol(1)).toBeSymbol()
expectTypeOf<symbol>().toBeSymbol()
```


toBeNull
--------


* **Type:** `() => void`


This matcher checks, if provided type is `null`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(null).toBeNull()
expectTypeOf<null>().toBeNull()
expectTypeOf(undefined).not.toBeNull()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(null).toBeNull()
expectTypeOf<null>().toBeNull()
expectTypeOf(undefined).not.toBeNull()
```


toBeUndefined
-------------


* **Type:** `() => void`


This matcher checks, if provided type is `undefined`.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(undefined).toBeUndefined()
expectTypeOf<undefined>().toBeUndefined()
expectTypeOf(null).not.toBeUndefined()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(undefined).toBeUndefined()
expectTypeOf<undefined>().toBeUndefined()
expectTypeOf(null).not.toBeUndefined()
```


toBeNullable
------------


* **Type:** `() => void`


This matcher checks, if you can use `null` or `undefined` with provided type.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf<1 | undefined>().toBeNullable()
expectTypeOf<1 | null>().toBeNullable()
expectTypeOf<1 | undefined | null>().toBeNullable()
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf<1 | undefined>().toBeNullable()
expectTypeOf<1 | null>().toBeNullable()
expectTypeOf<1 | undefined | null>().toBeNullable()
```


toBeCallableWith
----------------


* **Type:** `() => void`


This matcher ensures you can call provided function with a set of parameters.



ts
```
import { expectTypeOf } from 'vitest'

type NoParam = () => void
type HasParam = (s: string) => void

expectTypeOf<NoParam>().toBeCallableWith()
expectTypeOf<HasParam>().toBeCallableWith('some string')
```


```
import { expectTypeOf } from 'vitest'

type NoParam = () => void
type HasParam = (s: string) => void

expectTypeOf<NoParam>().toBeCallableWith()
expectTypeOf<HasParam>().toBeCallableWith('some string')
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.



toBeConstructibleWith
---------------------


* **Type:** `() => void`


This matcher ensures you can create a new instance with a set of constructor parameters.



ts
```
import { expectTypeOf } from 'vitest'

expectTypeOf(Date).toBeConstructibleWith(new Date())
expectTypeOf(Date).toBeConstructibleWith('01-01-2000')
```


```
import { expectTypeOf } from 'vitest'

expectTypeOf(Date).toBeConstructibleWith(new Date())
expectTypeOf(Date).toBeConstructibleWith('01-01-2000')
```



**WARNING**If used on a non-function type, it will return `never`, so you won't be able to chain it with other matchers.



toHaveProperty
--------------


* **Type:** `<K extends keyof T>(property: K) => ExpectTypeOf<T[K>`


This matcher checks if a property exists on the provided object. If it exists, it also returns the same set of matchers for the type of this property, so you can chain assertions one after another.



ts
```
import { expectTypeOf } from 'vitest'

const obj = { a: 1, b: '' }

expectTypeOf(obj).toHaveProperty('a')
expectTypeOf(obj).not.toHaveProperty('c')

expectTypeOf(obj).toHaveProperty('a').toBeNumber()
expectTypeOf(obj).toHaveProperty('b').toBeString()
expectTypeOf(obj).toHaveProperty('a').not.toBeString()
```


```
import { expectTypeOf } from 'vitest'

const obj = { a: 1, b: '' }

expectTypeOf(obj).toHaveProperty('a')
expectTypeOf(obj).not.toHaveProperty('c')

expectTypeOf(obj).toHaveProperty('a').toBeNumber()
expectTypeOf(obj).toHaveProperty('b').toBeString()
expectTypeOf(obj).toHaveProperty('a').not.toBeString()
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/api/expect-typeof.html>

assertType
==========


* **Type:** `<T>(value: T): void`


You can use this function as an alternative for [`expectTypeOf`](expect-typeof) to easily assert that the argument type is equal to the generic provided.



ts
```
import { assertType } from 'vitest'

function concat(a: string, b: string): string
function concat(a: number, b: number): number
function concat(a: string | number, b: string | number): string | number

assertType<string>(concat('a', 'b'))
assertType<number>(concat(1, 2))
// @ts-expect-error wrong types
assertType(concat('a', 2))
```


```
import { assertType } from 'vitest'

function concat(a: string, b: string): string
function concat(a: number, b: number): number
function concat(a: string | number, b: string | number): string | number

assertType<string>(concat('a', 'b'))
assertType<number>(concat(1, 2))
// @ts-expect-error wrong types
assertType(concat('a', 2))
```



 © 2021-Present Anthony Fu  
© 2021-Present Matias Capeletto  
Licensed under the MIT License.  

<https://vitest.dev/api/assert-type.html>

vitest