49. Writing readable unit tests
TL;DR (5 lines)
- Tests are evidence of a specific claim.
- Different layers prove different things.
- A compact flow is enough to teach testing structure.
- Invalid paths deserve explicit fixtures.
- The chapter should teach proof design, not ritual.
Frequent mistakes
- Treating every test as the same kind of evidence.
- Adding giant scenarios where a small invariant test would be stronger.
- Explaining tooling before explaining the proof obligation.
Prerequisites: book/chapters/48-tracing-and-observability.html. See also: book/chapters/48-tracing-and-observability.html, book/chapters/27-grammar.html, book/chapters/31-build-errors.html.
Concrete Problem
Testing chapters often become lists of test names instead of explanations of what evidence each layer should provide.
Red Thread (Single Project)
One feature is checked by a unit-level invariant, a scenario-level flow, and an invalid-path assertion.
For what
This chapter helps the reader design tests as evidence, not ceremony.
What you are going to do
You will inspect one tested flow, then classify which part belongs to unit, scenario, regression, or generation-oriented validation.
Coherent example
space demo/tests
proc classify_score(x: int) -> int {
if x < 0 { give 11 }
if x > 100 { give 12 }
give 0
}
Global explanation
Testing pages should explain what each test proves. A useful chapter distinguishes local invariants, end-to-end scenarios, regression proof, and failure-focused fixtures without collapsing them into one vague category.
Invalid case
proc bad_test_surface(x: int) -> int {
if x { give 11 }
give 0
}
This invalid case is intentionally small. It exists to isolate the contract failure that the chapter is trying to teach.
Common pitfalls
- Treating every test as the same kind of evidence.
- Adding giant scenarios where a small invariant test would be stronger.
- Explaining tooling before explaining the proof obligation.
Short exercise
Take the example and write one invariant it needs, one scenario it needs, and one invalid-path check it needs.
Summary in 5 points
- Tests are evidence of a specific claim.
- Different layers prove different things.
- A compact flow is enough to teach testing structure.
- Invalid paths deserve explicit fixtures.
- The chapter should teach proof design, not ritual.
Mini quiz
- What contract is the coherent example trying to make explicit?
- Why does the invalid example fail?
- What boundary should remain visible if you extend the example?
See also
Next best action
Extend the coherent example by one small, justified step and keep the same contract visible from input to output.