A Guess With a Test Case Number

A checkbox that saves to the Account instead of the Order produced a false pass on the next run. Three ways sandbox state decides your result before step one.

A test that starts from an unverified precondition is not a test.

It is a guess. The test case number on it does not change that.

Three Ways State Decided the Result Before Step One

The clearest example was a checkbox. In the sign-up journey there is a "Customer Vulnerable" flag, and setting it unlocks a free battery backup unit as an add-on.

That checkbox does not save to the Order. It saves to the Account, permanently.

So a leftover true from one test run silently unlocks the add-on in the next run — on a different order, in a different story, for a tester who never ticked anything. The add-on appears, the case passes, and the pass is worthless. Nobody knows, because a false pass produces no artefact. It produces a green row.

The second was a chain. Every in-life journey — terminate, amend, service change — requires the full acquisition sequence beforehand: attract, then join, then activate. A tester who skips it and reuses a sandbox account from a previous run starts from a state nobody has verified, hits a failure, and files it against the story under test.

The story is usually fine. The account was broken before the first step.

The third was a field nobody mentions. Two paid add-ons only appear in the telesales cart when the account has a particular router model. On an account with a different router, the product list is simply empty. No message, no explanation, no "not available for this account."

An empty list looks exactly like a feature that has not been deployed yet. A tester who set up a perfectly reasonable account, without ever thinking about router type, cannot tell those two situations apart.

The Property All Three Share

In each case, the outcome of the test was decided by state the test case never mentions.

That is the mechanism, and it is worth stating plainly because it cuts across every technique you already use. Boundary values, equivalence classes, decision tables — all of them operate on the inputs of the test. None of them say anything about the state the test starts in, or the state it leaves behind.

Two failure modes come out of it, and they feel completely different from the inside.

A false pass happens when leftover state makes something available that the code under test did not actually enable. Nothing looks wrong. You will not investigate a green result.

A false fail happens when missing setup makes something unavailable that the code does provide. That one you will investigate — for hours, in the wrong place, and often with a defect raised against a developer who did nothing wrong.

The second wastes a day. The first ships.

Why This Class Escapes

None of these three were undocumented. That is the uncomfortable part.

The persistence of the vulnerable flag was written down — as a quick answer in a journey note, with no warning attached about what it does to test data. The acquisition chain rule was written down too, once, in a global file, and never repeated in the individual journey files where somebody would actually be reading during execution. The router dependency was real system behaviour that simply never appeared in the story description.

So the knowledge existed and the tester still had no way to reach it. Documentation that lives one file away from the moment of need is, operationally, documentation that does not exist.

Which makes this a test design problem rather than a documentation problem. The fix is not "write more"; it is "write it where the test is."

What Belongs Inside the Test Case

The rule I now apply: a test case owns its state at both ends. Not the environment, not the tribal knowledge, not the global file. The case.

  • Write the setup chain into the case as numbered steps, not as an assumption. If a journey requires three preceding journeys, those are three lines in the precondition block, each with the state it must produce. "Account exists" is not a precondition — "account has an activated service created through join and activate in this run" is.
  • List every hidden field the feature silently depends on, with its required value. Router model, account type, a flag set three journeys ago. If a mandatory setup field does not appear in the test, every failure it causes will be reported as a system bug, and that misattribution costs more than the line would have.
  • Put permanent, record-level flags in a teardown checklist, not only in the step that sets them. Anything that writes to the Account rather than the Order outlives your test. If you do not reset it, every subsequent test on that account inherits the state — including tests written by people who have never read your case.

Two of those are about arriving. One is about leaving. The leaving half is the one almost nobody writes, because the test is finished by then and the tester has moved on.

The Diagnostic Question for an Empty Screen

There is a specific moment where all of this converges: you run a step, and the screen shows nothing.

Empty product list. No options. No error.

Before raising anything, ask one question. Is this "not available in this system" or "not available for this data"? They render identically and they are opposite findings — one is a defect, the other is your own setup.

Answering it takes a second account with the dependency deliberately satisfied. That is five minutes, and it is the difference between a defect report that earns trust and one that quietly spends it.

Where I Would Start

Take one journey your team runs often. Read its test cases and mark every sentence that assumes something about the starting account.

Then check what those assumptions are actually based on — a documented setup chain, or the fact that it worked last time.

Anything in the second category is not covered. It ran, it passed, and neither of those facts is about the software.

If someone ran your test case on a brand-new sandbox tomorrow, would it start from the state you think it does?