Vitest
Expert assistance with Vitest - Blazing fast unit test framework.
Overview
Vitest is a Vite-native testing framework:
-
Fast: Powered by Vite, instant HMR
-
Compatible: Jest-compatible API
-
TypeScript: First-class TypeScript support
-
Coverage: Built-in coverage with v8/istanbul
-
UI: Beautiful UI for test results
Installation
npm install --save-dev vitest npm install --save-dev @vitest/ui npm install --save-dev @testing-library/react @testing-library/jest-dom
Configuration
// vitest.config.ts import { defineConfig } from 'vitest/config'; import react from '@vitejs/plugin-react';
export default defineConfig({ plugins: [react()], test: { globals: true, environment: 'jsdom', setupFiles: './src/test/setup.ts', coverage: { provider: 'v8', reporter: ['text', 'html', 'json'], }, }, });
Setup File
// src/test/setup.ts import { expect, afterEach } from 'vitest'; import { cleanup } from '@testing-library/react'; import * as matchers from '@testing-library/jest-dom/matchers';
expect.extend(matchers);
afterEach(() => { cleanup(); });
Basic Tests
import { describe, it, expect } from 'vitest';
describe('Math functions', () => { it('adds numbers', () => { expect(1 + 1).toBe(2); });
it('multiplies numbers', () => { const result = 2 * 3; expect(result).toEqual(6); }); });
Testing React Components
import { render, screen } from '@testing-library/react'; import { describe, it, expect } from 'vitest'; import { Button } from './Button';
describe('Button', () => { it('renders with text', () => { render(<Button>Click me</Button>); expect(screen.getByText('Click me')).toBeInTheDocument(); });
it('handles click events', async () => { const handleClick = vi.fn(); render(<Button onClick={handleClick}>Click</Button>);
await userEvent.click(screen.getByText('Click'));
expect(handleClick).toHaveBeenCalledOnce();
}); });
Mocking
import { vi } from 'vitest';
// Mock function const mockFn = vi.fn(); mockFn('hello'); expect(mockFn).toHaveBeenCalledWith('hello');
// Mock return value const mockFn = vi.fn().mockReturnValue(42); expect(mockFn()).toBe(42);
// Mock async function const mockFn = vi.fn().mockResolvedValue('data'); const result = await mockFn(); expect(result).toBe('data');
// Mock module vi.mock('./api', () => ({ fetchCertificate: vi.fn().mockResolvedValue({ id: '1', subject: 'CN=test' }), }));
Best Practices
-
Describe Blocks: Group related tests
-
Clear Names: Write descriptive test names
-
AAA Pattern: Arrange, Act, Assert
-
One Assertion: Test one thing at a time
-
Mock External: Mock external dependencies
-
Coverage: Aim for high coverage
-
Fast Tests: Keep tests fast
-
Isolation: Tests should be independent
-
User Events: Use userEvent over fireEvent
-
Accessibility: Test with accessible queries
Resources
-
Documentation: https://vitest.dev