From requirements to test cases: a repeatable method

Good test design is not a talent. It is a four-step method you can apply to any requirement, from a one-line story to a full spec.

Every tester has stared at a one-line requirement — "the user can reset their password" — and wondered where to start. Writing good test cases from requirements is not a talent; it is a repeatable method. Mine has four steps: hunt the ambiguity, expand acceptance criteria into positive, negative, and edge cases, apply boundary analysis and equivalence classes, and keep traceability light enough that you actually maintain it.

Step 1: hunt the ambiguity first

Before writing anything, interrogate the requirement. "The user can reset their password" hides a dozen open questions. How is the reset delivered — email, SMS, both? Does the link expire, and after how long? Can an unverified account request one? What happens on the third failed attempt? Every question you ask in refinement is a bug that never gets written. I keep a running list of ambiguity triggers: words like "quickly," "should," "supported," any passive sentence that hides who acts, and any description that covers only the happy path.

Step 2: turn acceptance criteria into test cases

Each acceptance criterion generates three families of cases:

The order matters. Positive cases confirm the requirement; negative and edge cases test the requirement itself, and they are where most of the real defects live.

Step 3: boundaries and equivalence, in plain language

Equivalence classes sound academic, but the idea is simple: if two inputs will take the same path through the system, you only need one of them. For a password field that allows 8–64 characters, testing 25, 30, and 42 characters tells you nothing that testing 30 didn't. Boundary analysis is the other half: bugs cluster at the edges, so test exactly at the limits — 7, 8, 64, and 65 characters — not somewhere comfortable in the middle. Together the two techniques cover more behavior with fewer cases, which also keeps the suite cheap to maintain later.

Step 4: traceability without heavyweight tools

You do not need a requirements-management platform to know which cases cover which requirement. A naming convention does most of the work: prefix each case with the story ID — PWD-12-pos-01, PWD-12-neg-03. In JIRA, linking the test task to the story gives you the reverse direction for free. When a requirement changes, one search tells you exactly which cases need review. That is the whole point of traceability: not an audit artifact, but a fast answer to "what do I need to update?"

A worked example

Take this requirement: "Users can apply one discount code per order; codes are 6–10 alphanumeric characters."

  1. Ambiguities: is the code case-sensitive? What message appears for an expired code? Can a code be removed and replaced before checkout? Does "per order" survive an abandoned cart?
  2. Positive: a valid 6-character code applies; a valid 10-character code applies; the discount is reflected in the total and at payment.
  3. Negative: a second code is rejected with a clear message; 5- and 11-character codes are rejected; a code with symbols is rejected; an expired code is rejected.
  4. Edge: apply, remove, and re-apply the same code; apply a code, then change the cart below its minimum spend; paste a code with a trailing space; submit while offline.

Ten minutes of method produced more than a dozen cases, and at least three of them — the trailing space, the cart change, the replace flow — would never appear if I had only read the requirement and "tested that it works."

Takeaway: before writing any test cases, write down every question the requirement does not answer. The questions are the real test plan; the cases are just their formal version.

The method costs discipline, not time. And it compounds: the negative and edge cases you invent for one feature become a personal checklist you reuse on every feature after it.