Lesson 25 / 25

A Frontend Testing Checklist

Review a test suite before you rely on it.

Questions to ask of every suite

Does the runner fit the project (Vitest for Vite, Jest where it is established) with a simulated DOM only where needed? Do tests follow arrange-act-assert, test one behaviour each and use precise matchers? Are async assertions awaited, and are timers, dates and randomness controlled? Are mocks limited to boundaries, with the network mocked by MSW and unhandled requests failing? Do component tests use accessible queries, user-event and findBy/waitFor instead of sleeps? Are snapshots small and reviewed? Does a custom render provide the real providers with fresh state? Is coverage used to find gaps, not as a target? Does CI run the suite once, in parallel or sharded, with flaky tests tracked?

The checklist

Use it in code review.

[ ] runner chosen deliberately; jsdom / happy-dom only for DOM tests; setup file in place
[ ] one behaviour per test; names read as sentences; arrange-act-assert
[ ] precise matchers; asymmetric matchers for ids and timestamps
[ ] every async assertion awaited (no-floating-promises lint on)
[ ] fake timers / pinned dates / seeded randomness; TZ fixed
[ ] mocks restored after each test; module mocks only at boundaries
[ ] network mocked with MSW; onUnhandledRequest: 'error'
[ ] queries by role / label first; getByTestId only as last resort
[ ] userEvent.setup() + awaited interactions; findBy / waitFor, never sleep
[ ] small, reviewed snapshots only
[ ] custom render with real providers and fresh state per test
[ ] coverage reviewed for untested branches; modest thresholds
[ ] CI: run once, parallel / sharded, JUnit + coverage artefacts; flaky tests ticketed
[ ] end-to-end flows covered separately (Playwright / Cypress)

Delete tests that never catch anything useful

A test that breaks on every refactor but has never caught a real bug costs more than it gives. Rewrite it around behaviour, or remove it.

Quick check: Which item belongs on a healthy frontend testing checklist?

  • Tests rely on fixed sleeps for async UI
  • Every component has a full-page snapshot
  • Network calls are mocked with MSW and unhandled requests fail the test
  • Coverage must be exactly 100%
Answer

Network calls are mocked with MSW and unhandled requests fail the test — Deterministic, behaviour-focused, boundary-mocked tests.