Philosophy
Write tests first. Tests encode requirements, not implementation details.
Coverage means behavior covered end-to-end, not test count — a green suite full of
isolated unit tests can coexist with a completely broken product.
Integration Tests (Preferred)
Test real flows end-to-end. Prefer integration tests that exercise the actual
application stack over isolated unit tests.
Unit Tests (Justify Every One)
Default to zero unit tests. Write one only when it catches something an
integration test cannot reasonably catch — and be able to state, in one line,
what that something is. Logic that typically clears this bar:
- State machines
- Calculations
- Validation rules
- Parsing logic
Belonging to this list is not the justification by itself — the justification is
the concrete failure the unit test catches that the integration suite would miss
(e.g. an edge-case input matrix too expensive to drive through the full stack).
A unit test that cannot be justified this way is a removal candidate, not coverage.
UI Component Testing (Frontend Stacks)
When the project includes a frontend framework, classify each component before choosing test types.
Classification Heuristic
| Category |
Detection Signals |
Test Types |
| Presentational |
Props/inputs only, no services, no HTTP, no state store |
Skip standalone tests — covered by parent integration tests. Exception: 3+ conditional branches warrant a focused test. |
| Smart/Container |
Injects services, uses state management, makes HTTP calls, lifecycle logic |
Integration tests (Component Harness / Testing Library) + unit tests for complex service interactions |
| Form-heavy |
Reactive/template forms, custom validators, multi-step flows |
Integration tests for form submission flows. Unit tests only for custom validators with complex rules. |
| Critical User Journey |
Auth, checkout, payment, data deletion, onboarding |
E2E tests (Playwright Test) + integration tests for individual screens |
| Visual/Layout |
Pure styling, responsive layout, theme switching, design-token-driven |
Visual regression tests (Playwright Test toHaveScreenshot). Playwright CLI for interactive spot-checks during dev only. |
| Data Display |
Tables, lists, charts with transformations |
Integration tests verifying data binding and transformation |
Quality-First Rule
When a component spans multiple categories, apply ALL applicable test types.
Test Type Definitions
| Test Type |
What It Tests |
Tools |
| Unit |
Isolated logic (services, validators, pipes) |
Framework test runner |
| Integration / Component |
Component + real DOM + dependencies |
Component Harness (Angular), Testing Library (React/Vue) |
| E2E |
Full user journey across pages |
Playwright Test (npx playwright test) |
| Visual |
Layout, styling, responsive behavior |
Playwright Test (toHaveScreenshot) for regression; Playwright CLI (playwright-cli) for ad-hoc dev verification |
Browser Testing Tools
Two-tier model — Playwright Test for CI, Playwright CLI for interactive dev work:
| Purpose |
Tool |
Requires |
| Interactive browser automation |
Playwright CLI (playwright-cli) |
npm i -g @playwright/cli |
| Visual regression / E2E (CI) |
Playwright Test (toHaveScreenshot, npx playwright test) |
@playwright/test |
Rules:
- Playwright Test for anything repeatable — tests live in the repo, run in CI
- Playwright CLI for interactive browser work — navigation, screenshots, snapshots, form filling, network inspection during development
- Prefer the project's established browser tooling — use Playwright CLI for
interactive checks when it is installed; do not introduce another browser driver
solely for an ad-hoc check
- Interactive tools are NOT a substitute for tests — if it matters enough to verify, write a Playwright Test
Anti-Patterns — NEVER DO THESE
- Hardcode magic values just to make tests pass
- Assert implementation details (call counts, internal method names)
- Copy expected values from implementation — tests should encode requirements, not mirror code
- Mock-heavy unit tests that re-verify wiring — mocking every collaborator and asserting the mocks were called proves the test agrees with the implementation, not that the product works
- Unit tests that would stay green while the product is broken — if the real flow can fail without this test failing, the test is false confidence, not coverage
Good Assertions
Assert behavior and business rules:
- Status codes and response shapes
- Business state transitions
- Data presence/absence based on requirements
- Error conditions that requirements specify
Stack-specific test patterns are in the stack pack skills (e.g., stack-dotnet, stack-angular).
1---2name: testing3description: TDD patterns and test quality guidelines. Use when writing tests, setting up test infrastructure, TDD workflow, integration tests, unit tests, test strategy, mocking, test fixtures, test helpers, assertion patterns, test coverage, red-green-refactor cycle, failing tests, test quality review, or test anti-patterns.4---56## Philosophy7Write tests first. Tests encode requirements, not implementation details.8Coverage means behavior covered end-to-end, not test count — a green suite full of9isolated unit tests can coexist with a completely broken product.1011## Integration Tests (Preferred)12Test real flows end-to-end. Prefer integration tests that exercise the actual13application stack over isolated unit tests.1415## Unit Tests (Justify Every One)16Default to zero unit tests. Write one only when it catches something an17integration test cannot reasonably catch — and be able to state, in one line,18what that something is. Logic that typically clears this bar:1920- State machines21- Calculations22- Validation rules23- Parsing logic2425Belonging to this list is not the justification by itself — the justification is26the concrete failure the unit test catches that the integration suite would miss27(e.g. an edge-case input matrix too expensive to drive through the full stack).28A unit test that cannot be justified this way is a removal candidate, not coverage.2930## UI Component Testing (Frontend Stacks)3132When the project includes a frontend framework, classify each component before choosing test types.3334### Classification Heuristic3536| Category | Detection Signals | Test Types |37|---|---|---|38| **Presentational** | Props/inputs only, no services, no HTTP, no state store | Skip standalone tests — covered by parent integration tests. Exception: 3+ conditional branches warrant a focused test. |39| **Smart/Container** | Injects services, uses state management, makes HTTP calls, lifecycle logic | Integration tests (Component Harness / Testing Library) + unit tests for complex service interactions |40| **Form-heavy** | Reactive/template forms, custom validators, multi-step flows | Integration tests for form submission flows. Unit tests only for custom validators with complex rules. |41| **Critical User Journey** | Auth, checkout, payment, data deletion, onboarding | E2E tests (Playwright Test) + integration tests for individual screens |42| **Visual/Layout** | Pure styling, responsive layout, theme switching, design-token-driven | Visual regression tests (Playwright Test `toHaveScreenshot`). Playwright CLI for interactive spot-checks during dev only. |43| **Data Display** | Tables, lists, charts with transformations | Integration tests verifying data binding and transformation |4445### Quality-First Rule46When a component spans multiple categories, apply ALL applicable test types.4748### Test Type Definitions4950| Test Type | What It Tests | Tools |51|---|---|---|52| Unit | Isolated logic (services, validators, pipes) | Framework test runner |53| Integration / Component | Component + real DOM + dependencies | Component Harness (Angular), Testing Library (React/Vue) |54| E2E | Full user journey across pages | Playwright Test (`npx playwright test`) |55| Visual | Layout, styling, responsive behavior | Playwright Test (`toHaveScreenshot`) for regression; Playwright CLI (`playwright-cli`) for ad-hoc dev verification |5657## Browser Testing Tools5859Two-tier model — **Playwright Test** for CI, **Playwright CLI** for interactive dev work:6061| Purpose | Tool | Requires |62|---|---|---|63| Interactive browser automation | Playwright CLI (`playwright-cli`) | `npm i -g @playwright/cli` |64| Visual regression / E2E (CI) | Playwright Test (`toHaveScreenshot`, `npx playwright test`) | `@playwright/test` |6566**Rules**:671. **Playwright Test for anything repeatable** — tests live in the repo, run in CI682. **Playwright CLI for interactive browser work** — navigation, screenshots, snapshots, form filling, network inspection during development693. **Prefer the project's established browser tooling** — use Playwright CLI for70 interactive checks when it is installed; do not introduce another browser driver71 solely for an ad-hoc check724. **Interactive tools are NOT a substitute for tests** — if it matters enough to verify, write a Playwright Test7374## Anti-Patterns — NEVER DO THESE75- Hardcode magic values just to make tests pass76- Assert implementation details (call counts, internal method names)77- Copy expected values from implementation — tests should encode requirements, not mirror code78- Mock-heavy unit tests that re-verify wiring — mocking every collaborator and asserting the mocks were called proves the test agrees with the implementation, not that the product works79- Unit tests that would stay green while the product is broken — if the real flow can fail without this test failing, the test is false confidence, not coverage8081## Good Assertions82Assert behavior and business rules:83- Status codes and response shapes84- Business state transitions85- Data presence/absence based on requirements86- Error conditions that requirements specify8788Stack-specific test patterns are in the stack pack skills (e.g., stack-dotnet, stack-angular).