Files
english/.opencode/skills/web-testing/references/unit-integration-testing.md
2026-04-12 01:06:31 +07:00

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