Test the behavior that matters
Choose checks by consequence and evidence, from pure rules to complete user tasks.
Why this matters
Picture your invitation flow breaking next week. Which check would catch it before a user does? A useful test fails when behavior people depend on goes wrong. Pick the smallest trustworthy level for that behavior, then use rendered and human review for what code assertions cannot settle.
What to understand
There is no universal ratio or time budget for these tests. One thin integration test can beat dozens of unit tests that mirror implementation details. Test through roles, labels, and visible outcomes where you can. Ask your agent: "are we asserting observable behavior, not component internals or class order?"
Watch for
- Tests asserting component internals, class order, or exact copy instead of observable behavior.
- A mocked API treated as proof the real API checks permissions or is safe to retry.
- Flaky timing patched with longer sleeps instead of waiting for meaningful state.
- Visual baselines updated just to make CI green, without deciding the new look is correct.
- A passing build mistaken for proof that search, keyboard use, or clipboard behavior works.
Strong default
Start with consequence: denied access, data loss, duplicate side effects, important validation, and the primary journey. Use explicit test logins and isolated test data. Prefer stable setup, fixed test data, and waiting for meaningful state — fix flaky timing, don't raise every timeout.
When this doesn't apply
A static copy change rarely needs a new test asserting exact wording. Don't rerun everything without new evidence — broaden checks when a new failure or changed dependency warrants it, rather than treating coverage percentage as the goal.
In practice
| Question | Useful evidence |
|---|---|
| Does a validation or calculation rule hold? | Focused unit tests around boundaries. |
| Can the user complete a component interaction? | Integration tests through accessible controls. |
| Do browser, API, and saved data work together? | End-to-end checks with isolated test data. |
| Did composition or wrapping change? | Rendered review or intentional visual regression captures. |
| Can someone use an assistive input path? | Keyboard and screen-reader task replay, supported by automation. |
| Does the system meet a load or timing constraint? | Measurement under stated conditions. |
For an invitation flow, useful checks include: a viewer cannot invite by direct request; invalid input stays editable; repeating an action does not create duplicates; a queued email is not shown as delivered.
A mocked API — a stand-in that pretends to be the real service — can prove your UI handles a timeout. It does not prove the real API is safe to retry without creating duplicates, or that it checks permissions. Cover each claim at the right boundary. A failing test should say what changed and be reproducible.
Verify
Run the repo's relevant lint, type, test, and build commands, then replay the critical task against the combined changes. For UI changes, include narrow, intermediate, and wide layouts plus a content stress. For shared components, check representative consumers and states.
Related skills
Ask your agent to run $readiness to interpret the result for release. Continue with observability for what tests cannot tell you about real production use.
Last updated on