This trace follows the actual state transitions behind the companion Choose Tests by the Failure They Can Catch. It describes a common execution path; implementation details can vary, so keep the contract separate from the mechanism.
Step 1: Name the contract at risk
Tests provide evidence about behavior at different boundaries. Unit tests isolate a small decision; integration tests exercise collaboration between components; end-to-end tests validate a user-visible path. Each level trades feedback speed, realism, and setup cost differently.
Step 2: Choose the right test boundary
A unit test can verify that a retry policy stops after its configured budget. An integration test can verify that the persistence adapter records an idempotency key. An end-to-end test can prove the checkout flow returns the expected result through the deployed browser-facing path.
Step 3: Set up controlled collaborators
Test the invariant at the narrowest level that can expose the failure, then add an integration check when collaboration between components is the risk.
At this point, record the state that changed and check the invariant before advancing. If the operation repeats, make clear which values persist and which are recomputed.
Step 4: Assert success and failure cases
High coverage does not prove meaningful behavior was asserted. Tests that duplicate implementation details can block harmless refactoring, while a few end-to-end tests may miss many edge cases. Choose representative contracts and include failure and boundary conditions.
Step 5: Use feedback to refine tests
A service test passes with a mocked database but production loses updates under concurrent requests. Which test layer was missing, and what invariant should the new test exercise?
The trace is complete when the result satisfies the stated contract. Compare this model with the concrete runtime or system you are studying before making a performance claim.