Testing Strategy: Unit and Integration
On this page
Testing Goals
- Prevent regressions in user critical flows.
- Make failures actionable and fast to triage.
- Avoid flakiness that reduces trust in CI.
Test Portfolio
- Unit: pure functions, reducers, selectors, validators.
- Integration: component trees, hooks plus UI, routing boundaries.
- End to end: a small number of core journeys, run less frequently.
Unit Tests: What to Target
- Reducers and state machines.
- Mapping functions from DTO to ViewModel.
- Validation logic and formatting.
- Permission and feature flag decisions.
Integration Tests: What to Target
- Render behavior for loading, error, empty, and ready states.
- Form submit orchestration including error mapping.
- Routing behavior including deep links and guarded routes.
- Error boundary fallbacks and recovery actions.
Selector Policy
- Prefer role based queries and accessible labels.
- Use data-testid only as a last resort for non semantic elements.
- Never depend on layout structure or CSS class names.
Mocking Policy
- Mock at the network boundary, not internal component details.
- Prefer mock server tools to simulate real API behavior.
- Do not over mock hooks and components, it creates false confidence.
Example: Testing UI States
function UsersView({ state }) {
if (state.status === "loading") return <div role="status">Loading</div>;
if (state.status === "error") return <div role="alert">Error</div>;
if (state.status === "empty") return <div>Empty</div>;
return <div>Ready</div>;
}
Flake Reduction Rules
- Avoid fixed timeouts. Wait for conditions.
- Control timers explicitly when testing debounced behavior.
- Stabilize async boundaries and do not race effects.
- Reset test environment between tests.
CI Gates
- Block merges on failing integration tests for critical flows.
- Track flaky test rate and quarantine with a time limit.
- Run fast unit tests on every commit, run slower suites on main branch.
Failure Modes
- Snapshot heavy tests that fail on harmless markup changes.
- Over mocked tests that do not detect integration regressions.
- Flaky tests caused by time based waits and uncontrolled async.
- Tests coupled to CSS and DOM structure instead of user visible behavior.
Release Checklist
- Critical flows have integration coverage.
- DTO mapping and validators have unit coverage.
- Tests use stable selectors and accessible queries.
- Flaky tests are tracked and fixed, not ignored.