Vitest - Быстрое тестирование
Что такое Vitest?
Vitest — это фреймворк для тестирования на базе Vite. Совместим с Jest API, но работает значительно быстрее благодаря Vite.
Установка
bash
npm install --save-dev vitest @vitest/uiКонфигурация
vite.config.ts
typescript
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
globals: true,
environment: 'node'
}
});vitest.config.ts (выделенная конфигурация)
typescript
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'node',
coverage: {
provider: 'v8'
}
}
});Основные отличия от Jest
| Параметр | Jest | Vitest |
|---|---|---|
| Скорость | ⚠️ Медленнее | ✅ Очень быстро |
| Hot reload | ❌ Нет | ✅ Да |
| TypeScript | ✅ Требует config | ✅ Out of the box |
| Vite интеграция | ❌ Нет | ✅ Встроена |
| API совместимость | - | ✅ Jest compatible |
Быстрый старт
bash
npm install --save-dev vitest
npx vitestНаписание теста
typescript
import { describe, test, expect } from 'vitest';
describe('Calculator', () => {
test('adds numbers', () => {
expect(1 + 1).toBe(2);
});
});Globals (Глобальные функции)
Если включены globals, не нужно импортировать:
typescript
// vitest.config.ts
export default defineConfig({
test: {
globals: true
}
});
// теперь можно писать без импорта
describe('Math', () => {
test('works', () => {
expect(2 + 2).toBe(4);
});
});Watch mode
bash
vitest # Watch mode по умолчанию
vitest --run # Один раз и выход
vitest --ui # UI интерфейс
vitest --coverage # С покрытиемMocking в Vitest
vi.fn()
typescript
import { vi, describe, test, expect } from 'vitest';
const mockFn = vi.fn();
mockFn('hello');
expect(mockFn).toHaveBeenCalledWith('hello');vi.mock()
typescript
import { vi } from 'vitest';
vi.mock('./api', () => ({
fetchUser: vi.fn(() => Promise.resolve({ id: 1 }))
}));vi.spyOn()
typescript
const obj = {
greet: (name) => `Hello ${name}`
};
const spy = vi.spyOn(obj, 'greet');
obj.greet('John');
expect(spy).toHaveBeenCalledWith('John');Async тестирование
typescript
test('async operation', async () => {
const result = await fetchData();
expect(result).toBeDefined();
});
// С таймаутом
test('long operation', async () => {
const result = await longRunningTask();
expect(result).toBe('done');
}, 10000); // 10 сек timeoutSnapshots
typescript
test('renders header', () => {
const component = render(<Header title="Test" />);
expect(component.html()).toMatchSnapshot();
});Обновить: vitest -u
Coverage (Покрытие)
bash
vitest --coverageКонфигурация:
typescript
// vitest.config.ts
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
exclude: [
'node_modules/',
'dist/'
]
}
}
});Параллельное выполнение
typescript
// vitest.config.ts
export default defineConfig({
test: {
threads: true,
maxThreads: 4,
minThreads: 1
}
});Matchers в Vitest
Все matcher'ы из Jest работают также в Vitest:
typescript
expect(value).toBe(5);
expect(value).toEqual(obj);
expect(fn).toHaveBeenCalled();
expect(value).toMatch(/regex/);Плюс дополнительные:
typescript
expect(value).rejects.toThrow(); // Для Promise
expect(value).resolves.toBe(5); // Для PromiseSetup файлы
typescript
// vitest.config.ts
export default defineConfig({
test: {
setupFiles: ['./vitest.setup.ts']
}
});
// vitest.setup.ts
import { beforeAll, afterAll } from 'vitest';
beforeAll(() => {
console.log('Тесты начались');
});
afterAll(() => {
console.log('Тесты закончились');
});Практический пример
typescript
// counter.ts
export class Counter {
private count = 0;
increment() {
this.count++;
}
decrement() {
this.count--;
}
get value() {
return this.count;
}
}
// counter.test.ts
import { describe, test, expect, beforeEach } from 'vitest';
import { Counter } from './counter';
describe('Counter', () => {
let counter: Counter;
beforeEach(() => {
counter = new Counter();
});
test('increment works', () => {
counter.increment();
expect(counter.value).toBe(1);
});
test('decrement works', () => {
counter.decrement();
expect(counter.value).toBe(-1);
});
test('multiple operations', () => {
counter.increment();
counter.increment();
counter.decrement();
expect(counter.value).toBe(1);
});
});UI Dashboard
bash
npx vitest --uiОткроет красивый интерфейс с результатами тестов.
Интеграция с IDE
VS Code
Установить расширение: Vitest
Будут отображаться статусы тестов прямо в редакторе.
Лучшие практики
✅ С Vitest:
- Используйте globals для удобства
- Запускайте тесты в watch mode при разработке
- Используйте UI для визуализации
- Включайте coverage для контроля качества
- Используйте параллельное выполнение
❌ Избегайте:
- ❌ Не полагайтесь на порядок выполнения
- ❌ Не используйте timing-зависимые тесты
- ❌ Не забывайте про cleanup в afterEach
Дальше
Изучите Unit Testing для написания эффективных модульных тестов.