Acceptance criteria are the contract. They state, before anyone writes code, what must be true for a requirement to count as delivered. Written well, they align four people and generate their own test cases. Written badly, they are decoration attached to a ticket, and the real acceptance decision gets made at the end by whoever is most tired.
The failure modes are predictable, which means they are avoidable.
The single test that catches most problems
Read the criterion and ask: could the system fail this?
If you cannot describe a concrete behaviour that would fail it, you have written a preference. Preferences are not criteria, and the difference is not pedantic. A criterion that cannot fail cannot be verified, so it cannot be part of the definition of done, so it will not be checked.
| Written | Can it fail? | Fix |
|---|---|---|
| The interface should be intuitive | No. Nothing observable fails this. | Name the observable outcome: a first-time user completes the flow without opening help. |
| Handle errors gracefully | No. Graceful is unmeasurable. | State the behaviour: on a timeout, the entry is preserved and a retry option appears. |
| Search should be fast | No. Fast is unbounded. | Bound it: results return within 2 seconds for a catalogue of 100,000 items. |
| The export contains all active users | Yes. You can produce an export missing one. | Already fine. |
Hand the criteria to someone who was not in the conversation and ask them to describe a way the system could fail each one. Every criterion they cannot answer for is one that needs rewriting.
Cover the paths people avoid
Most criteria describe the case where everything works. That case is real, and it is also the one least likely to produce a defect. The value is in the rest.
- The happy path. State it, briefly. It is the baseline everything else varies from.
- The empty case. No results, no data, first use, nothing selected. Almost never specified, almost always reached.
- The boundaries. If a rule changes at a threshold, say what happens exactly at it, not just either side.
- The invalid case. Wrong format, wrong type, out of range. What the user sees, and what happens to what they already entered.
- The failure case. A dependency is unavailable or slow. What the system does, and whether the operation is safe to retry.
- The permission case. Someone without rights attempts it. Blocked, and how.
Six lines of thought, and they eliminate the majority of late-discovered defects, because late-discovered defects are overwhelmingly in the paths nobody wrote down.
Given, When, Then, and when not to use it
The structured form is useful and over-applied.
Given a customer with an expired subscription
When they attempt to download an invoice
Then the download is blocked
And a renewal prompt is shown
It works because it forces you to state the precondition, which is where ambiguity hides. Most vague criteria are vague about context, not about outcome.
Use it for behavioural rules with real preconditions. Do not force it onto everything: a data constraint like "the report reconciles to the general ledger to the penny" is clearer as a plain sentence, and wrapping it in Given/When/Then adds ceremony without precision.
Key takeaways
- If you cannot describe a way the system could fail a criterion, it is a preference, not a criterion.
- Six paths cover most late defects: happy, empty, boundary, invalid, failure, permission.
- Ambiguity usually hides in the precondition, which is why stating context first helps.
- Criteria written after development are documentation of what got built, not agreement about what should be.
Common mistakes worth naming
Criteria that describe the implementation. "A dropdown appears in the top right." This locks the solution and, worse, hides the requirement. If the dropdown turns out to be the wrong control, nobody can tell what was actually needed.
Criteria that restate the title. A story called "user can reset password" with the criterion "the user can reset their password" has added nothing. The criterion needs to say what happens with an expired link, a wrong email, a second request before the first is used.
Too many criteria. Fifteen criteria on one story usually means it is several stories. Splitting is nearly always the right move, and the criteria are the signal telling you where the seams are.
Criteria written after the build. At that point they are a description, and the agreement they were supposed to create never happened.
How you know they are good
The practical test is downstream: hand the requirement to a QA Engineer and see whether they can design coverage without coming back with questions. If they can, the criteria did their job. If they come back with five questions, those five questions were about to become five silent assumptions in somebody's code.