Перейти к содержимому

5. Vitest: введение

Vitest

Vitest — современный тест-раннер для Vite-проектов. В 2-10× быстрее Jest благодаря нативной ESM поддержке и параллельному выполнению.

Окно терминала
npm install --save-dev vitest
# Для UI
npm install --save-dev @vitest/ui
# Для coverage
npm install --save-dev @vitest/coverage-v8
// vite.config.ts или vitest.config.ts
import { defineConfig } from 'vitest/config'
export default defineConfig({
test: {
environment: 'node', // или 'jsdom', 'happy-dom'
globals: true, // нет нужды импортировать expect, test
setupFiles: ['./src/test/setup.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'html'],
include: ['src/**/*.ts'],
},
},
})
package.json
{
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:run": "vitest run",
"test:coverage": "vitest run --coverage"
}
}

Vitest полностью совместим с Jest API — большинство тестов переносятся без изменений:

// Работает одинаково в Jest и Vitest
import { describe, it, expect, beforeEach, vi } from 'vitest'
describe('calculator', () => {
it('adds numbers', () => {
expect(1 + 1).toBe(2)
})
})
// Параллельные тесты внутри файла (осторожно с shared state)
import { describe, it, expect } from 'vitest'
describe.concurrent('parallel tests', () => {
it('test 1', async () => {
await someAsyncOperation()
expect(true).toBe(true)
})
it('test 2', async () => {
await anotherAsyncOperation()
expect(true).toBe(true)
})
})
Окно терминала
npx vitest --ui

Открывает интерактивный браузерный интерфейс с деревом тестов, ошибками и coverage.

import { expect, it } from 'vitest'
it('renders correctly', () => {
const result = formatUser({ name: 'Alice', role: 'admin' })
expect(result).toMatchSnapshot()
// При первом запуске: создаёт снапшот
// При последующих: сравнивает с сохранённым
})
// Inline snapshot
it('inline snapshot', () => {
expect(formatUser({ name: 'Bob' })).toMatchInlineSnapshot(`
{
"display": "Bob",
"initials": "B",
}
`)
})
// Обновить снапшоты
// npx vitest --update-snapshots
// Moки: vi вместо jest
import { vi } from 'vitest'
// jest.fn() → vi.fn()
const mockFn = vi.fn()
// jest.spyOn() → vi.spyOn()
const spy = vi.spyOn(console, 'log')
// jest.mock() → vi.mock()
vi.mock('./api', () => ({
fetchUser: vi.fn().mockResolvedValue({ name: 'Alice' })
}))
// jest.useFakeTimers() → vi.useFakeTimers()
vi.useFakeTimers()
// jest.setSystemTime() → vi.setSystemTime()
vi.setSystemTime(new Date('2024-01-15'))
vitest.config.ts
export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
setupFiles: ['./src/test/setup.ts'],
},
})
// src/test/setup.ts
import '@testing-library/jest-dom'
math.ts
export function add(a: number, b: number) {
return a + b
}
// Тесты прямо в исходнике (удаляются при сборке)
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest
it('adds correctly', () => {
expect(add(1, 2)).toBe(3)
})
}
vitest.config.ts
export default defineConfig({
test: {
includeSource: ['src/**/*.ts'],
},
define: {
'import.meta.vitest': 'undefined', // убрать в продакшн
},
})
  1. Создай Vite + TypeScript проект, добавь Vitest
  2. Перенеси Jest тесты в Vitest (измени импорты)
  3. Настрой coverage report и посмотри результат в HTML
  • Vitest быстрее Jest за счёт Vite и ESM
  • API совместим с Jest — миграция проста
  • vi вместо jest для моков и spy
  • Встроенный UI (vitest --ui) — удобно для разработки