Boundary Condition Enumeration¶
Why It Matters¶
Off-by-one errors, edge cases, and boundary confusion cause a disproportionate share of bugs. Human intuition is bad at boundaries - we think about the middle of ranges but forget the endpoints. Systematic enumeration catches cases like: what happens at zero? at maximum? when transitioning from A to B?
The Key Move¶
For any specification involving ranges, transitions, or cases, list all boundaries explicitly. For numeric ranges, check: minimum, maximum, zero, negative/positive transition, overflow. For state transitions, check: initial state, final states, loops, unreachable states. For each boundary, specify exactly what happens: is it included or excluded? defined or error?
Classic Application¶
Buffer overflow prevention. A buffer of size N accepts indices 0 through N-1. The boundary conditions are: what happens at -1 (before start)? at N (after end)? A correct implementation explicitly checks these boundaries and either rejects or handles them safely. Most buffer overflows come from unchecked boundary conditions.
Surprising Application¶
Relationship boundaries. "We should spend more time together" is ambiguous at boundaries. More than what? Up to how much? Enumerate: currently 2 hours/week, want at least 5, maximum sustainable is 15, optimal seems like 8-10. Now you can check if you're in range (yes, increase) or at limit (no, problem is quality not quantity).
Failure Modes¶
Boundary proliferation - obsessing over irrelevant boundaries while missing critical ones. Fence-post confusion - treating boundaries inconsistently (sometimes inclusive, sometimes exclusive). False dichotomies - treating continuous ranges as discrete boundaries. Analysis paralysis from trying to enumerate every conceivable boundary.
Go Deeper¶
Beizer, Software Testing Techniques, Chapter 4; Meyer, "Applying Design by Contract" (1992)