Vitest Fundamentals: Tests, Matchers & Setup
Vitest is a fast, Vite-native testing framework for JavaScript/TypeScript. It offers a Jest-compatible API while reusing Vite's build pipeline (esbuild) for near-instant test startup -- a project already configured with Vite for its build gets fast test execution without a separately-configured test bundler.
Basic Test Structure
import { describe, test, expect, beforeEach } from 'vitest'
describe('Calculator', () => {
let calc: Calculator
// Re-creates fresh state before EACH test -- prevents one test's
// mutations from leaking into the next
beforeEach(() => {
calc = new Calculator()
})
test('adds two numbers', () => {
expect(calc.add(2, 3)).toBe(5)
})
test('throws on division by zero', () => {
expect(() => calc.divide(10, 0)).toThrow('Division by zero')
})
}).toBe() vs .toEqual()
// toBe() checks strict equality (===) -- fails for objects/arrays
// with identical content but different references
expect({ a: 1 }).toBe({ a: 1 }) // FAILS
// toEqual() checks deep structural equality
expect({ a: 1 }).toEqual({ a: 1 }) // PASSESTesting Async Code
test('fetches user data', async () => {
const data = await fetchUser(1)
expect(data).toEqual({ id: 1, name: 'Alice' })
})
// test.each avoids copy-pasting near-identical test cases
test.each([
[1, 1, 2],
[2, 3, 5],
])('adds %i + %i to equal %i', (a, b, expected) => {
expect(a + b).toBe(expected)
})Running Tests & Shared Vite Config
// vite.config.ts -- Vitest can share the SAME config file as the
// app's build, so plugins/aliases apply to tests automatically
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom', // simulated DOM for component tests
globals: true,
},
})npx vitest # watch mode -- re-runs affected tests on save
npx vitest run # single pass, exits -- typical for CIKeep your own version of these notes — editable, searchable, and organised by your stack.
Start free