REACT Contents

Testing Strategy: Unit and Integration

Prioritize integration tests for user critical flows and keep unit tests for pure logic. Learn test pyramid constraints, stable selectors, mocking policy, and CI gates that prevent flaky UI tests.

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.