2.7 KiB
2.7 KiB
Unit & Integration Testing
Framework Comparison
| Framework | Speed | Best For |
|---|---|---|
| Vitest | Fastest | Modern projects, Vite |
| Jest | Fast | React/CRA legacy |
| Bun test | Ultra-fast | Bun projects |
Vitest Setup
// vitest.config.ts
export default defineConfig({
test: {
environment: 'jsdom', // or 'happy-dom'
globals: true,
coverage: { reporter: ['text', 'json', 'html'] },
},
});
Vitest Browser Mode (Real Browser)
// vitest.config.ts - higher fidelity than jsdom
export default defineConfig({
test: {
browser: {
enabled: true,
name: 'chromium',
provider: 'playwright',
},
},
});
When to use: Complex DOM interactions, CSS testing, browser APIs
Test Structure (AAA)
import { describe, it, expect, beforeEach } from 'vitest';
describe('UserService', () => {
let service: UserService;
beforeEach(() => {
service = new UserService();
});
it('creates user with valid data', () => {
// Arrange
const userData = { email: 'test@example.com' };
// Act
const user = service.create(userData);
// Assert
expect(user.id).toBeDefined();
expect(user.email).toBe('test@example.com');
});
it('throws on invalid email', () => {
expect(() => service.create({ email: 'invalid' }))
.toThrow('Invalid email');
});
});
Integration Test
describe('User API', () => {
let db: Database;
beforeAll(async () => {
db = new Database(':memory:');
await db.migrate();
});
afterEach(async () => {
await db.clearAllTables();
});
it('persists and retrieves user', async () => {
await db.users.insert({ email: 'test@example.com' });
const user = await db.users.findOne({ email: 'test@example.com' });
expect(user).toBeDefined();
});
});
Test Naming
// Good - describes behavior
it('should return 200 when valid token provided');
it('should throw ValidationError when email invalid');
// Bad - vague
it('test1');
it('works');
Mocking
import { vi } from 'vitest';
// Mock module
vi.mock('./api', () => ({
fetchUser: vi.fn().mockResolvedValue({ name: 'John' })
}));
// Spy
const spy = vi.spyOn(console, 'log');
expect(spy).toHaveBeenCalledWith('message');
Coverage Targets
| Area | Target |
|---|---|
| Critical paths | 100% |
| Core features | 80-90% |
| Overall | 75-85% |
Commands
npx vitest run # Run all
npx vitest # Watch mode
npx vitest run --coverage # Coverage
npx vitest run -u # Update snapshots
npx vitest --browser # Browser mode