Vite'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!
$ vitest -w
Vitest smartly searches the module graph and only rerun the related tests (just like how HMR works in Vite!).
vitest
, vitest dev
and vitest watch
are aliases and they all start vitest in watch mode by default. They also depend on the CI
environment variable, which if it appears to be defined, Vitest is going to run the tests only one time and not in watch mode, like vitest run
.
Components testing for Vue, React, Svelte, Lit and more
Out-of-box TypeScript / JSX support / PostCSS
ESM first, top level await
Workers multi-threading via tinypool (a lightweight fork of Piscina), allowing tests to run simultaneously. Threads are enabled by default Vitest, and can be disabled 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 of correctness for run performance).
Filtering, timeouts, concurrent for suite and tests
You can use CLI to filter test files by name:
$ vitest basic
Will only execute test files that contain basic
, e.g.
basic.test.ts
basic-foo.test.ts
You can optionally pass a timeout in milliseconds as third argument to tests. The default is 5 seconds.
import { test } from 'vitest'
test('name', async () => { ... }, 1000)
Hooks also can receive a timeout, with the same 5 seconds default.
import { beforeAll } from 'vitest'
beforeAll(async () => { ... }, 1000)
Use .skip
to avoid running certain suites or tests
import { describe, assert, 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);
});
});
Use .only
to only run certain suites or tests
import { describe, assert, 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);
});
});
Use .todo
to stub suites and tests that should be implemented
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");
});
Use .concurrent
in consecutive tests to run them in parallel
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 () => { /* ... */ });
it.concurrent("concurrent test 2", async () => { /* ... */ });
});
If you use .concurrent
in a suite, every tests in it will be run in parallel
import { describe, it } from 'vitest'
// All tests within this suite will be run in parallel
describe.concurrent("suite", () => {
it("concurrent test 1", async () => { /* ... */ });
it("concurrent test 2", async () => { /* ... */ });
it.concurrent("concurrent test 3", async () => { /* ... */ });
});
You can also use .skip
, .only
, and .todo
with concurrent suites and tests. Read more in the API Reference
Jest Snapshot support
Chai built-in for assertions plus Jest expect compatible APIs
Notice that if you are using third-party libraries that add matchers, setting test.globals
to true
will provide better compatibility
Tinyspy built-in for mocking with jest
compatible APIs on vi
object.
import { vi, expect } 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.returns[1]).toBe('world')
Vitest supports both happy-dom or jsdom for mocking DOM and browser APIs. They don't come with Vitest, you might need to install them:
$ npm i -D happy-dom
# or
$ npm i -D jsdom
After that, change the environment
option in your config file:
// vite.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
environment: 'happy-dom' // or 'jsdom', 'node'
}
})
Vitest supports Native code coverage via c8
{
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
}
}
To configure it, set test.coverage
options in your config file:
// vite.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
coverage: {
reporter: ['text', 'json', 'html']
}
}
})