Review — Testing Practices
Reviewer for local testing discipline. Read project test guides first when present, then apply
the neutral baseline below.
Scope
Applicable paths commonly include:
**/*.test.ts, **/*.test.tsx, **/*.spec.ts, **/*.spec.tsx
**/*.integration.test.ts, **/*.integration.test.tsx
**/*.msw.ts, test/**, src/test/**
*.stories.tsx, Storybook specs
e2e/**, Playwright/Cypress page objects and fixtures
If the repository has local test documentation, cite the relevant convention in findings.
Checklist
Test Location and Tiers
- Tests live near the code they cover unless the repository has a deliberate central test layout.
- Shared test infrastructure folders are not used as buckets for feature tests.
- Unit, integration, component, and e2e tiers are named and routed consistently.
- Fast feedback lanes stay fast; screenshot/component/e2e suites are not used for cheap unit
assertions.
- Coverage gates focus on changed risk, not low-value tests for trivial getters.
Network and Boundary Mocking
- For data-fetching UI, prefer rendering the real component/store and mocking only the network
boundary.
- Avoid mocking the API module in integration tests when the repository has network-level mock
infrastructure.
- Unhandled network requests fail loudly instead of silently hitting the real world.
- Mock handlers/fixtures are colocated and reusable by tests/stories where practical.
- Handler paths match the runtime test environment and avoid hard-coded origins unless required.
Behaviour Assertions
- Assert on user-visible DOM, callbacks, toasts, emitted events, or public state.
- Do not reach into private methods or internal fields unless the unit under test is explicitly a
low-level utility.
- Store-internal timing and concurrency can be unit-tested with lower-level mocks when that is
the clean seam.
Browser and E2E Determinism
- Tests create their own artifacts with unique names and assert on those artifacts.
- Avoid mutating or deleting seeded/shared environment data.
- Avoid env-wide assertions such as exact global counts,
.first(), or .nth(N) unless the test
owns the full dataset.
- No fixed sleeps; wait on assertions, events, responses, or polling predicates.
- Backend-dependent assertions wait on the response/event that proves the backend completed.
- Smoke tags are reserved for fast, reliable, load-bearing baseline flows.
- Locator priority prefers stable test ids and accessible roles over raw CSS selectors.
- Screenshot tests are avoided for heavy, unstable, or non-deterministic surfaces unless the
repository explicitly supports them.
Local Type and Build Gotchas
- Account for incremental compiler caches when validating newly added files.
- Generated/vendored files that are outside the lint/type project are ignored centrally rather
than hand-formatted into compliance.
Orchestrated Review Contract
When dispatched by review-orchestrator, follow the provided reviewer-input.schema.json payload. Return a REVIEW_RESULT object compatible with skills/review-orchestrator/reviewer-finding.schema.json, then a concise markdown summary. Keep findings evidence-based, include concrete suggested_fix for every blocker/major, and return NEEDS_CONTEXT instead of guessing when required context is missing.
Finding Format
### [F-NNN] Title
- **Severity**: blocker | major | minor | info
- **File**: path/to/test.ts:line
- **Problem**: which testing rule is violated
- **Why it matters**: determinism, confidence, CI runtime, or maintenance impact
- **Fix**: concrete test rewrite or fixture/handler change
Severity guidance: real-network leaks, shared-data mutation, fixed sleeps, and backend-race
assertions are usually major or blocker; substrate choice and smoke tagging are usually
minor unless they make CI flaky.
1---2name: review-testing-practices3description: Use when reviewing unit, integration, Storybook, component, or e2e tests against repository-local testing conventions: co-location, network mocking, MSW-style boundary mocks, behaviour assertions, deterministic waits, smoke/full split, locator priority, and screenshot-test discipline. Dispatched by review-orchestrator for --testing-practices, --project-conventions, --all, or changed test/e2e/story files.4license: MIT5---67# Review — Testing Practices89Reviewer for local testing discipline. Read project test guides first when present, then apply10the neutral baseline below.1112---1314## Scope1516Applicable paths commonly include:1718- `**/*.test.ts`, `**/*.test.tsx`, `**/*.spec.ts`, `**/*.spec.tsx`19- `**/*.integration.test.ts`, `**/*.integration.test.tsx`20- `**/*.msw.ts`, `test/**`, `src/test/**`21- `*.stories.tsx`, Storybook specs22- `e2e/**`, Playwright/Cypress page objects and fixtures2324If the repository has local test documentation, cite the relevant convention in findings.2526---2728## Checklist2930### Test Location and Tiers3132- Tests live near the code they cover unless the repository has a deliberate central test layout.33- Shared test infrastructure folders are not used as buckets for feature tests.34- Unit, integration, component, and e2e tiers are named and routed consistently.35- Fast feedback lanes stay fast; screenshot/component/e2e suites are not used for cheap unit36 assertions.37- Coverage gates focus on changed risk, not low-value tests for trivial getters.3839### Network and Boundary Mocking4041- For data-fetching UI, prefer rendering the real component/store and mocking only the network42 boundary.43- Avoid mocking the API module in integration tests when the repository has network-level mock44 infrastructure.45- Unhandled network requests fail loudly instead of silently hitting the real world.46- Mock handlers/fixtures are colocated and reusable by tests/stories where practical.47- Handler paths match the runtime test environment and avoid hard-coded origins unless required.4849### Behaviour Assertions5051- Assert on user-visible DOM, callbacks, toasts, emitted events, or public state.52- Do not reach into private methods or internal fields unless the unit under test is explicitly a53 low-level utility.54- Store-internal timing and concurrency can be unit-tested with lower-level mocks when that is55 the clean seam.5657### Browser and E2E Determinism5859- Tests create their own artifacts with unique names and assert on those artifacts.60- Avoid mutating or deleting seeded/shared environment data.61- Avoid env-wide assertions such as exact global counts, `.first()`, or `.nth(N)` unless the test62 owns the full dataset.63- No fixed sleeps; wait on assertions, events, responses, or polling predicates.64- Backend-dependent assertions wait on the response/event that proves the backend completed.65- Smoke tags are reserved for fast, reliable, load-bearing baseline flows.66- Locator priority prefers stable test ids and accessible roles over raw CSS selectors.67- Screenshot tests are avoided for heavy, unstable, or non-deterministic surfaces unless the68 repository explicitly supports them.6970### Local Type and Build Gotchas7172- Account for incremental compiler caches when validating newly added files.73- Generated/vendored files that are outside the lint/type project are ignored centrally rather74 than hand-formatted into compliance.7576---7778## Orchestrated Review Contract7980When dispatched by `review-orchestrator`, follow the provided `reviewer-input.schema.json` payload. Return a `REVIEW_RESULT` object compatible with `skills/review-orchestrator/reviewer-finding.schema.json`, then a concise markdown summary. Keep findings evidence-based, include concrete `suggested_fix` for every blocker/major, and return `NEEDS_CONTEXT` instead of guessing when required context is missing.8182---8384## Finding Format8586```markdown87### [F-NNN] Title8889- **Severity**: blocker | major | minor | info90- **File**: path/to/test.ts:line91- **Problem**: which testing rule is violated92- **Why it matters**: determinism, confidence, CI runtime, or maintenance impact93- **Fix**: concrete test rewrite or fixture/handler change94```9596Severity guidance: real-network leaks, shared-data mutation, fixed sleeps, and backend-race97assertions are usually `major` or `blocker`; substrate choice and smoke tagging are usually98`minor` unless they make CI flaky.99