# Testing Strategy — 1-Page

**Thesis**: Tests are documentation that runs. Write tests that catch bugs, not tests that pass.

**Refrain**: Test behavior, not implementation. Mock at boundaries. Fast tests run often.

---

## The Pyramid

```
      E2E (few, slow)
    Integration (some)
  Unit (many, fast)
```

## When to Use What

| Level | Test For | Speed |
|-------|----------|-------|
| **Unit** | Pure logic, utils, transforms | <10ms |
| **Integration** | API routes, component + hooks | ~100ms |
| **E2E** | Critical user flows | ~seconds |

## Test Structure (AAA)

```typescript
test('adds item to cart', () => {
  // Arrange
  const cart = new Cart();
  
  // Act
  cart.add({ id: '1', price: 10 });
  
  // Assert
  expect(cart.total).toBe(10);
});
```

## Mock at Boundaries

| Mock | Don't Mock |
|------|------------|
| External APIs | Your own code |
| Database | Pure functions |
| `Date.now()` | Implementation details |

## MSW (API Mocking)

```typescript
import { http, HttpResponse } from 'msw';

const handlers = [
  http.get('/api/users/:id', ({ params }) => {
    return HttpResponse.json({ id: params.id, name: 'Test' });
  }),
];
```

## Component Testing

```typescript
test('button calls onclick', async () => {
  const onclick = vi.fn();
  render(Button, { props: { onclick } });
  
  await fireEvent.click(screen.getByRole('button'));
  
  expect(onclick).toHaveBeenCalledOnce();
});
```

## Query Priority

```typescript
// Best (accessible)
screen.getByRole('button', { name: 'Submit' });
screen.getByLabelText('Email');

// Okay
screen.getByText('Welcome');

// Last resort
screen.getByTestId('submit-btn');
```

## Factory Pattern

```typescript
function createUser(overrides = {}) {
  return {
    id: faker.string.uuid(),
    name: faker.person.fullName(),
    email: faker.internet.email(),
    ...overrides,
  };
}
```

## Coverage Targets

Enforced floors match `frontend/vitest.config.ts` (included files only). After B4d (local): **~91%** statements / **~74%** branches / **~94%** lines on included files; Codecov project **82.98%** — recovery complete; see [coverage-and-eslint plan](../../plans/archive/6-7-26/coverage-and-eslint.md).

| Metric | Vitest floor (included files) |
|--------|-------------------------------|
| Statements | 75% |
| Branches | 54% |
| Functions | 78% |
| Lines | 75% |

## Anti-Patterns

| Bad | Good |
|-----|------|
| Test implementation | Test behavior |
| Mock everything | Mock boundaries |
| Shared state | Reset between tests |
| No assertions | Assert something |

## Definition of Done

- [ ] Unit tests for pure logic
- [ ] Integration tests for API routes
- [ ] Component tests for UI behavior
- [ ] MSW for API mocking
- [ ] Coverage meets Vitest floors (`vitest.config.ts`) and Codecov CI status (see [coverage-and-eslint](../../plans/archive/6-7-26/coverage-and-eslint.md))
- [ ] Tests run in CI

---
