When, Not Whether
A cancellation email fires at order submission, not at completion. A tax exemption applies forward-only, never retroactively. Both defeat the intuitive test, and both are timing conditions nobody wrote down.
The email arrived. The test passed. The test was wrong.
Not wrong about whether the message was sent — wrong about the moment it was sent, which was the only interesting property it had.
Two Clocks
Every requirement runs on two clocks, and they rarely show the same time.
The first is business narrative time. When a customer cancels, we send them a message. That sentence describes an outcome and implies a moment: at the end, when the cancellation is real.
The second is implementation time. The message actually fires at order submission — the instant the request is raised, not when the termination process completes. And it does not repeat.
Both clocks are correct about whether. They disagree about when, and the disagreement never appears in the story description. In that case it existed only in a decisions file, which is not the document anyone writes test cases from.
What Testing the Wrong Moment Produces
Two failure modes, and the second one is worse.
The obvious failure is a false defect. A tester works through the termination journey, reaches the end, checks the inbox, finds nothing new, and files "cancellation email not sent". The email was sent. It was sent twenty minutes and four orchestration steps earlier, while the tester was still working.
The subtler failure is a false confirmation. The tester reaches the end of the journey, looks in the inbox, and the message is sitting there — because it arrived at submission and inboxes do not expire. The case passes. What now sits in the suite is a green row asserting that the system sends the message on completion.
That row is a documented lie about the trigger point, and it will be inherited by everyone who runs the suite afterwards. The day the behaviour actually changes, the test still passes.
A test that checks the right thing at the wrong moment is not a weak test. It is a test with an incorrect assertion that happens to be green.
The Same Problem With a Flag
Now take a state instead of an event.
Marking an account tax exempt affects only invoices generated after the flag is set. Historical invoices are untouched. Clear the flag and the very next invoice recalculates tax normally. The flag reaches the billing system through the standard async orchestration, with no manual push involved.
The intuitive test is: did the old invoices recalculate?
They did not, and they never will, because there is no retroactivity by design. A tester who runs that check has two ways to be wrong. They can file a false defect against unchanged history. Or they can note the absence of retroactivity as a limitation, mistaking a deliberate design decision for a gap.
The real assertions are a different shape entirely. Forward-only: the next invoice generated after the flag is set carries no tax. Reversible: clear the flag, generate again, tax returns.
Neither of those is a harder test than the intuitive one. They are just aimed at a different point on the timeline.
The Rule
Timing is not an attribute of a test case. It is a test condition in its own right, and it needs to be pinned down before the case is written.
For an event, that means the trigger point and the repeat behaviour. For a state, it means the temporal scope — does this apply to records that already exist, or only to ones created afterwards?
Neither question is answered by the sentence that describes the feature. Business sentences describe outcomes. Outcomes have no timestamps.
The Clock Interview
Five questions, asked of a developer or an architect, before anyone writes a case. None of them takes longer than a minute to answer, and the answers are what the test cases are actually made of.
- At exactly which system event does this fire? Order submission, orchestration completion, a status change, a scheduled job. Get the event, not the phase of the process it sits in.
- Does it repeat, and under what conditions? A message that fires once and a message that fires on every retry need different assertions and produce different bug reports when they misbehave.
- Does this apply to existing records or only to new ones? For any exempt, enable, activate or override flag, this is the first question, not a detail. It decides whether your historical data is evidence or a distraction.
- How does the value propagate, and how long does it take? Async orchestration means "not there yet" and "not there" look identical for a while. If nobody tells you the expected latency, you will eventually file one of them as the other.
- What happens when it is undone? Reversibility is where flags are least tested and most often wrong, and it is usually a single extra step in a case you are already running.
Why This Escapes So Reliably
Because timing is where the requirement and the implementation are allowed to differ without anybody noticing.
A story description that says the customer is notified when they cancel is not wrong. It is silent. Silence in a requirement is not treated as a gap, it is treated as detail — and detail is assumed to be somebody else's problem until a test has to assert something specific.
Then the decision that resolved the silence lives somewhere else. A decisions log, a design note, a thread. Somewhere that is genuinely available and genuinely not read by the person writing test cases against the story.
So the tester supplies the missing timestamp themselves, from the business sentence, using intuition. Intuition says the goodbye message comes at the end, because that is when a goodbye makes sense. Intuition says an exemption applies to your account, and your invoices are part of your account, so surely the old ones change too.
Intuition is a reasonable default and it is wrong about half the time, which is exactly the rate that makes it dangerous.
The cheap correction is to treat every trigger and every flag as having a clock attached, and to write the clock into the test condition explicitly — the moment, the repeat, the scope, the latency, the undo. Five short answers, recorded against the case, where the next person will find them.
In your last suite, which case asserts an outcome without ever stating when the system was supposed to produce it?