Skip to content

Acceptance Criteria: How to Write Ones QA Can Pass or Fail

ILIA KARPENKO4 min read

Acceptance criteria are the conditions a user story has to meet before anyone calls it done: a short list of statements a tester can check off as pass or fail, agreed before development starts, not negotiated after. A story without them is a title and a hope. A story with vague ones is barely better, because the disagreement about what "done" means just moves from planning to the sprint review.

The cost shows up at the worst possible time. A developer builds against their own reading of the story, QA tests against a different reading, and the gap surfaces in UAT or, worse, in production, after the two conversations that should have caught it during refinement. Fixing a criterion at that point costs a rework cycle. Fixing it before a line of code exists costs one sentence.

What makes a criterion testable

A testable criterion has three properties. It is binary: a specific input produces a specific, observable outcome, and either that outcome happens or it doesn't. It is single: one condition per criterion, because a compound one ("the form validates and shows a helpful error") can pass on the first half and fail on the second with no clean way to record that. And it names a subject a tester can actually check, not an internal quality no one can observe from outside the system.

Not testableTestable
The page loads quicklyThe dashboard renders its first chart within 1.5 seconds at the 95th percentile
Invalid input is handled wellSubmitting a non-numeric value in the quantity field shows "Enter a number" and blocks submission
The export works for large filesExporting a 50,000-row report completes and produces a file matching the on-screen row count
Users can recover their accountA user who requests a password reset receives an email with a link valid for 30 minutes

The left column reads like a requirement. None of the four rows can fail a test, because no observed behavior contradicts them. The right column can.

Free and open sourceCasely writes these cases for youAttach a spec and one file of your team's existing test cases in Claude. Casely copies your columns, names the gaps it found in the spec, and exports a single Excel file your tracker imports in one pass.Read the install docs

The Given/When/Then format

Given/When/Then structures a criterion as a starting state, an action, and a result: Given the account has a saved payment method, When the user completes checkout, Then the order confirms without asking for payment details again. The format forces the three pieces a testable criterion needs anyway: a defined starting point, a single triggering action, and one checkable outcome.

It also surfaces the negative cases a happy-path list skips. Write the criterion above, then ask what happens when the saved card is expired. Given the account has an expired payment method, When the user completes checkout, Then the order is blocked and the user is prompted to update the card. That second criterion rarely gets written unvouched, and it is usually the one QA finds a bug against first.

How many criteria does a story need

Enough to cover the happy path, the realistic failure paths, and the edge cases that would embarrass the team if a user found them first, and no more. A login story needs criteria for correct credentials, wrong password, locked account, and expired session, four or five statements. It does not need a criterion for every possible malformed input a security scanner might try. That belongs in a separate test charter, not the story that gates a sprint demo.

A story that grows past eight or ten criteria is usually two stories wearing one title. Split it. Reviewing twenty criteria in a single refinement session is where teams start rubber-stamping the back half of the list.

Where this breaks down

Criteria written after the code exists describe what the code does, not what it should do. They pass by construction, which defeats the purpose. Write them during refinement, before an estimate goes on the story, so a developer building the feature is building toward the criteria rather than backfilling them.

A binary pass/fail criterion can still hide a bad decision. "The system logs the user out after 30 minutes of inactivity" is perfectly testable and can still be the wrong number for the product, chosen by whoever wrote the ticket rather than by anyone who thought about the tradeoff. Testability tells you the criterion can be checked. It says nothing about whether the criterion is right.

Given/When/Then scales badly past simple, single-trigger interactions. A multi-step workflow with branching state, three different roles, and four permission levels turns into a wall of near-duplicate Given/When/Then blocks that nobody rereads carefully. A decision table or a state diagram communicates that shape better than another twelve lines of the same template.

What's worth automating

Turning an agreed set of criteria into structured test cases, one case per criterion, correctly formatted with steps and an expected result, is a mechanical transformation once the criteria exist. Deciding which criteria a story actually needs, catching the compound one that should split into two, and judging whether "30 minutes" is the right number for this product: that stays a conversation between the person who understood the problem and the person who has to test it.

Open sourceThe skill lives on GitHubMIT licensed, no account, nothing to install on your machine. Star it if it saves you an afternoon.View the repository