Skip to content

Test Case

beta  ·  Family qa-docs  ·  Phase develop  ·  Sizes lean, full  ·  ~2,200 tokens

The specification of one verification: what must be true before it runs, what is done, and what must happen as a result, written so that someone who is not its author can ask the same question tomorrow and get the same answer. A design artifact, not a record of a run: it carries no actual result and no pass or fail.

The short card. Why the document is shaped this way, and the argument behind every rule here, is in test-case_companion.md. A fully worked instance is test-case_example.md.

  • A verification must be repeatable by someone who is not you, next month.
  • A defect has been fixed and you want it to stay fixed: a regression case is the guard.
  • The behavior is high-risk (entitlement, money, data loss) and you want the check reviewed before it runs.
  • The work is regulated or audited and every requirement must link to a test.
  • A behavior needs checking under a configuration matrix, where “I tried it” is not evidence.
  • Once, throwing away. Checking something during development that nobody will re-run. Do the check.
  • Instead of exploring. Cases verify what you already thought of. They do not find the thing you did not think of, and a suite that grows while nobody explores is a quiet failure mode.
  • To hit a number. If cases are being written because a count is being watched, the count is the problem.
  • As a bug report. A test case is written before, to define correct behavior; a bug report is written after, because something was not.
  • As a test plan. The plan scopes and ranks the effort; the case is one unit inside it.
  • As a record of a run. No actual-result or pass/fail field belongs in the specification. One case, many runs.

Case, scenario, script, or criterion? (the question people actually have)

Section titled “Case, scenario, script, or criterion? (the question people actually have)”
You want to say Write
What must be true for the business to accept this story An acceptance criterion (acceptance-criteria)
How we verify one specific behavior, repeatably A test case (this template)
What we are testing, at a high level, before designing cases Most teams call this a test scenario
The ordered sequence in which a set of cases is run Most teams call this a test script or procedure

A warning about those last two rows. The ISTQB glossary does not draw the line most practitioners draw: it gives test procedure and test script identical definitions, and defines test scenario as a synonym for test script rather than as a high-level description. Your team’s usage is probably the folk taxonomy, and that is fine. What is not fine is assuming everyone shares it. Write down which you mean; the vocabulary will not settle it for you (companion section 8).

And the one that matters most. Acceptance criteria are agreed with the business before the work; test cases are designed by whoever tests, and they continue past the agreement into negative paths, boundaries, regression and non-functional checks that nobody signed off on. Some practitioners argue the two should be merged, and that is a real position with real practitioners behind it. Whichever you choose, choose it deliberately: the failure mode is assuming the criteria already cover what test design would have found (companion section 6).

Lean (four sections) is the default and should stay the default: Identification and Traceability, Preconditions and Test Data, Steps and Expected Results, Postconditions and Teardown. A test case is written hundreds of times over a project, so every field costs hundreds of times.

Full (eight sections) adds Design Rationale, Environment and Configuration, Automation Status, and Version and Approval. Reach for it when:

  • the work is regulated or audited and the case is evidence;
  • cases are reviewed as artifacts, not just executed;
  • the case is configuration-sensitive and a result is meaningless without the configuration;
  • the suite is large enough that knowing why a case exists is what lets you retire it.

Note that the master catalog marks this type single-size. This bundle ships two anyway, for the reasons in companion section 4; the catalog’s size calls are hypotheses, and this is one tested against evidence.

Score each 0, 1 or 2. Under 11 out of 16 and the case will not survive its first re-run by someone else.

# Criterion 0 1 2
1 One objective Verifies several unrelated things Mostly one thing Exactly one objective, stated in the title
2 Traceable Traces to nothing Named loosely Traces to a specific ID: criterion, requirement, risk or defect
3 Preconditions real None stated Vague (“user is logged in”) Specific enough that a stranger can construct the state
4 Expected results pre-written Blank or written after the run Present but vague Observable, specific, and written before execution
5 No execution state Has actual-result and pass/fail fields One creeping in Pure specification; runs recorded elsewhere
6 Independent Requires another case to run first Implicit ordering Runs in any order; postconditions stated
7 Right level of detail Every click, or “check it works” Uneven A competent stranger could run it; no more than that
8 Title survives a redesign Describes the click path Mixed Describes the behavior and the condition
  1. The single-use case. Actual-result and status fields baked into the specification, so the reusable artifact and one run’s record are the same file. Fix: keep run state in the tool.
  2. Retrofitted expectations. Expected results written after execution. They cannot fail. Fix: write them first, always.
  3. The three-in-one. One case verifying three things, so a failure tells you nothing. Fix: split it.
  4. Order dependence. Passes in the suite, fails alone, because a predecessor left state behind. Fix: real preconditions, real teardown.
  5. Click-by-click. Every UI interaction enumerated, so the case breaks on a redesign that broke nothing. Fix: specify behavior and data, not the path.
  6. “Log in and check it works.” Not repeatable by anyone but the author. Fix: preconditions and an observable expected result.
  7. The orphan. Traces to nothing, so nobody can tell whether it still matters, and it is never deleted. Fix: every case names what it covers.
  8. Counting cases. “We have 5,000 tests” says nothing, and once the count is a target it gets gamed with shallow cases. Fix: measure risk coverage, never volume.

pairs_with: [deliver-edge-cases]. There is no testing or QA skill in the pm-skills library (finding EC-4 in the repository’s STATE.md). deliver-edge-cases is the one honest pairing, and for this member it is a particularly direct one: the edge-case catalog it produces is exactly the negative, boundary and error-state territory that acceptance criteria do not cover, which is where a large share of test cases should come from. See companion sections 6 and 8.

test-case_template-lean.md · ~2,200 tokens

---
title: "{{case_title}}"
case_id: "{{case_id}}"
verifies: "{{what_this_traces_to}}"
priority: "{{priority}}"
case_status: "{{case_status}}"
last_updated: "{{date}}"
doc_type: test-case
size: lean
source_template: test-case
source_template_version: 0.1.0
---
<!--
LEAN TEST CASE. The smallest specification that is still a real test case: what it verifies and what it
traces to, what must be true before it runs, the steps paired with what should happen, and the state it
leaves behind. Use it for everyday cases written and run by one team. To grow it into a reviewable,
auditable case (see test-case_template-full.md), ADD sections; never rename or reorder the ones below,
because the full variant is a strict superset of this one.
A TEST CASE IS A DESIGN ARTIFACT, NOT A RECORD OF A RUN. There is deliberately no "actual result" and no
pass/fail field below. Those belong to an execution record: one case is run many times, and a specification
that carries the outcome of one run can only be used once. `case_status` above is the lifecycle of this
SPECIFICATION (draft, active, deprecated), not the outcome of a test. See test-case_companion.md sections 3
and 7.
ONE CASE, ONE OBJECTIVE. A case that verifies three things tells you almost nothing when it fails. One
objective does not mean one assertion; a single outcome may need several checks to confirm it.
WHAT A TEST CASE IS, AND IS NOT
It is the specification of ONE verification. It is NOT a test plan (that scopes and ranks a whole effort),
NOT a bug report (that is written after something failed), NOT a test run (that is an execution event), and
NOT necessarily the same thing your team means by "test scenario" or "test script" - those words are used
inconsistently across the industry and even the certification glossary. See test-case_companion.md section 8.
HOW TO FILL THIS IN
1. Read the comment under each heading: WHAT it wants, WHY it matters (with a pointer into
test-case_companion.md), guiding questions to ASK, a GOOD and a WEAK example, and the TRAP to avoid. For
the steps table, PRIORITY explains the ordering rule and ROW HINT says what a good row contains.
2. Replace each {{placeholder}} with your content. Write the expected results BEFORE you run anything.
3. If a section does not apply, write "N/A" and one line of why, rather than deleting it.
4. Before you share it: self-grade against test-case_guide.md, then DELETE every HTML comment. They are
guidance, not content.
-->
# {{case_id}}: {{case_title}}
## Identification and Traceability
<!-- WHAT What this case verifies in one sentence, and what it traces to: an acceptance criterion, a
requirement, a risk in the test plan, or a defect it now guards against. Plus its priority.
WHY A case that traces to nothing is a case nobody can ever decide to delete, which is how suites turn
into landfill. Traceability is also what an audit is actually auditing: linking every requirement
to its test. Deep dive: test-case_companion.md section 3 (Identification and Traceability).
ASK What single thing does this verify? What does it trace to, by ID? Why does this case exist - which
risk or criterion would go uncovered without it? How important is it relative to the others?
GOOD "Verifies that a restricted viewer opening a shared view receives only rows within their
entitlement. Traces to: test plan risk R-05 (High). No acceptance criterion covers this case; it
comes from test design, not from the agreed criteria. Priority: P1."
WEAK "Tests sharing. Priority: high." (verifies nothing specific, traces to nothing, and gives no
reason to keep or delete it next year)
TRAP A title that describes the click path ("open Views menu, click Share") rather than the behavior. A
behavior title survives a redesign; a path title does not. -->
{{identification_and_traceability}}
## Preconditions and Test Data
<!-- WHAT The system state, accounts, permissions and configuration that must exist before step 1, and the
specific data this case uses.
WHY This is what decides whether anyone other than the author can run the case and get the same
answer. Practitioners rank understandability and repeatability at the top of what makes a case
good, and a missing precondition is the usual cause of a case that "only works for Priya". Deep
dive: test-case_companion.md section 3 (Preconditions and Test Data).
ASK What must already be true: which accounts, which permissions, which feature flags, which data?
What values does this case feed in? Where does that data come from, and who creates it? What must
NOT be true (a state that would invalidate the run)?
GOOD "Preconditions: saved_views flag on; dashboard DB-7 exists with a Region filter; user R (restricted
viewer) has dashboard access but no entitlement to region EMEA; user O (owner) has a view on DB-7
filtered to region=EMEA, scope=shared. Data: view SV-31; users O and R from the standard persona
set."
WEAK "A shared view exists and a user opens it." (which user, with what entitlement, on which
dashboard, filtered to what? Two testers will construct two different tests)
TRAP Folding preconditions into step 1. A precondition is state that must already hold; a step is
something the test does. Merging them makes the case unrepeatable and hides its dependencies. -->
{{preconditions_and_test_data}}
## Steps and Expected Results
<!-- WHAT The actions in order, each paired with what should happen. One row per step.
WHY The pairing is the case. A step with no expected result is navigation, not verification. And the
expected result has to be written BEFORE the run: filled in afterwards it is a description of what
happened, which can never fail. Deep dive: test-case_companion.md section 3 (Steps and Expected
Results).
ASK What is the smallest sequence that exercises this one objective? What should happen at each step,
observably? Which step is the actual verification, as opposed to setup? How would a tester know it
failed?
PRIORITY Keep the sequence minimal: every step that is not needed to reach or observe the behavior is
maintenance you pay for forever. Specify behavior and data, not the click path. Do NOT add an
"actual result" or "pass/fail" column; those belong to the run record.
ROW HINT A good row has an action a competent stranger could perform without guessing, and an expected
result that is observable and specific enough to be wrong. A weak row says "verify it works".
GOOD | 3 | As user R, open dashboard DB-7 and select saved view SV-31 | The view loads. Rows are limited
to regions R is entitled to; no EMEA row appears in the table or in any aggregate total |
WEAK | 3 | Open the shared view | It works correctly |
TRAP Enumerating every click. Over-specified cases break on cosmetic UI changes that broke nothing, and
reviewers stop reading them. Under-specified cases cannot be repeated. Aim for what a competent
tester unfamiliar with the feature needs, and no more. -->
| # | Action | Expected result |
|---|---|---|
| {{step_number}} | {{action}} | {{expected_result}} |
## Postconditions and Teardown
<!-- WHAT The state the system is left in, and anything that must be cleaned up before the next case runs.
WHY A suite is a set of cases where one case's postcondition often becomes the next one's
precondition. A case that quietly leaves state behind becomes a hidden dependency, and that is the
usual reason a test passes alone and fails in a suite. Deep dive: test-case_companion.md section 3
(Postconditions and Teardown).
ASK What has changed in the system after this case runs? Does anything need deleting, resetting or
re-seeding? Can this case run twice in a row without cleanup? Does anything it leaves behind
affect another case?
GOOD "No data is created or modified; the case is read-only. User R's session is ended to avoid
carrying an authenticated session into the next case."
WEAK (section deleted, or "N/A" with no explanation)
TRAP Skipping this because the case "does not change anything". Say that explicitly instead - "no state
change; read-only" is information, and it is what tells the next person they can run this case in
any order. -->
{{postconditions_and_teardown}}

The reasoning, the history and every source, in the repository:

  • Companion - the long-form argument: why these sections, where the sources disagree, and what the bundle refuses to claim
  • History - what changed in this bundle, and when
  • Research log - every source consulted, with what each one actually supports
  • Catalog metadata - the machine-readable record this page is generated from

Catalog record: 8 sections across 1 format(s), methodology methodology-agnostic, typically owned by QA Engineer.