Testing strategy
Test behaviour at the cheapest level that gives confidence, then use browser tests for the journeys that only make sense as a whole.
Different failures need different tests
Pure transformations, validation, and domain rules are cheap to unit test. Integration tests are better for database access, authentication, caching, and mutations working together. End-to-end tests protect a small number of critical user journeys.
Do not force every async Server Component through a client-oriented component harness if an integration test explains the behaviour more naturally.
Mutation tests should include the unhappy paths
- Authenticated and unauthenticated callers.
- Authorised and unauthorised resources.
- Valid and invalid input.
- Successful writes and expected conflicts.
- Cache invalidation after the write.
- Idempotency where retries are possible.
Test the states users actually see
- Loading.
- Empty.
- Success.
- Validation failure.
- Unexpected error.
- Not found.
- Slow network where timing changes the experience.
Development mode is not production
Run tests against a production build for the flows where bundling, caching, routing, or server behaviour matters. Development mode deliberately behaves differently in several areas.
CI should at least catch type errors, lint failures, test failures, and a broken production build before deployment.
Can you explain “Testing strategy” without reaching for the API reference?
Describe the main trade-off, one failure mode, and the decision you would make in a real project.