vitest
A blazing fast unit test framework powered by Vite.
This project is currently in closed beta exclusively for Sponsors.
Become a Sponsor of @patak-js or @antfu to access the source code and issues tracker.
⚠️ DISCLAIMER: Vitest is still in development and not stable yet. It's not recommended to use it in production.
Features
- Vite's config, transformers, resolvers, and plugins.
- Jest Snapshot
- Chai for assertions
- Sinon for mocking
- JSDOM for DOM mocking
- Async suite / test, top level await
- ESM friendly
- Out-of-box TypeScript support
- Suite and Test filtering (skip, only, todo)
import { it, describe, expect, assert } from 'vitest'
describe('suite name', () => {
it('foo', () => {
expect(1 + 1).toEqual(2)
expect(true).to.be.true
})
it('bar', () => {
assert.equal(Math.sqrt(4), 2)
})
it('snapshot', () => {
expect({ foo: 'bar' }).toMatchSnapshot()
})
})
$ npx vitest
Configuration
vitest will read your root vite.config.ts when it present to match with the plugins and setup as your Vite app. If you want to it to have a different configuration for testing, you could either:
- Create
vitest.config.ts, which will have the higher priority - Pass
--configoption to CLI, e.g.vitest --config ./path/to/vitest.config.ts - Use
process.env.VITESTto conditionally apply differnet configuration invite.config.ts
To configure vitest itself, add test property in your Vite config
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
test: {
// ...
}
})
Global APIs
By default, vitest does not provide global APIs for explicitness. If you prefer to use the APIs globally like Jest, you can pass the --global option to CLI or add global: true in the config.
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
test: {
global: true
}
})
To get TypeScript working with the global APIs, add vitest/global to the types filed in your tsconfig.json
// tsconfig.json
{
"compilerOptions": {
"types": [
"vitest/global"
]
}
}
Browser Mocking
Pass --jsdom option in CLI to enable browser mocking. Or the jsdom flag in the config.
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
test: {
jsdom: true
}
})
Watch Mode
$ vitest -w
Vitest will smartly search for the module graph to only rerun the related tests.
Filtering
Skipping suites and tasks
Use .skip to avoid running certain suites or tests
describe.skip('skipped suite', () => {
it('task', () => {
// Suite skipped, no error
assert.equal(Math.sqrt(4), 3)
})
})
describe('suite', () => {
it.skip('skipped task', () => {
// Task skipped, no error
assert.equal(Math.sqrt(4), 3)
})
})
Selecting suites and tests to run
Use .only to only run certain suites or tests
// Only this suite (and others marked with only) are run
describe.only('suite', () => {
it('task', () => {
assert.equal(Math.sqrt(4), 3)
})
})
describe('another suite', () => {
it('skipped task', () => {
// Task skipped, as tests are running in Only mode
assert.equal(Math.sqrt(4), 3)
})
it.only('task', () => {
// Only this task (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
// 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 task
describe('suite', () => {
it.todo('unimplemented task')
})
TODO
- Reporter & Better output
- Task filter
- Mock
- Global Mode & Types
- Parallel Executing
- CLI Help
- JSDom
- Watch
- Source Map
- Coverage
Sponsors
Credits
Thanks to:
- @patak-js for the awesome package name!
- The Vite team for brainstorming the initial idea.
- @pi0 for the idea and implementation of using Vite to transform and bundle the server code.
- @lukeed for the work on uvu where we are inspired a lot from.
License
MIT License © 2021 Anthony Fu