How to write test cases and checklists: web and API examples
Test documentation earns its keep when another person can repeat a check, understand coverage and make a quality decision. Using one checkout flow, this guide shows when a detailed test case is worth maintaining, when a checklist is enough and how to avoid paperwork that protects no real risk.
Choose the artifact before filling a template
The same scenario does not need the same format forever. A team testing a 3-D Secure payment flow for the first time benefits from a precise case that records the return states. Once the flow is stable and checked weekly by an experienced team, a focused checklist may be easier to maintain.
Base the decision on product risk, data setup, tester familiarity and evidence requirements. More expensive failures and more hidden conditions justify more detail. A mandatory TMS field is not a reason by itself.
| Situation | Choose | Reason |
|---|---|---|
| New payment flow | Test case | Exact data, steps and evidence matter |
| Known release smoke | Checklist | Speed and critical-path coverage matter |
| Regulated control | Test case | Repeatability and history are required |
| Exploratory session | Charter + notes | Not every useful step is known in advance |
Test-case anatomy: make every claim testable
A useful minimum is an identifier, title, requirement link, preconditions, test data, actions, expected results and execution status. Author, component, priority and automation fields help only when the team actually uses them for ownership or reporting.
A precondition is an existing state: the buyer is signed in, the cart contains a product and the order currency is set. “Create a user” is setup work, not a state. For complex setup, link a fixture, API call or data builder that produces the state reliably.
- The title states action, condition and outcome.
- One step contains one action; an expected result sits where it becomes observable.
- Data is concrete: test_declined_01 and SKU-1842, not “valid values”.
- Expected results cover UI, API, stored state and side effects when those are in scope.
- Pass means every material expectation was checked, not merely that a green screen appeared.
Worked example: checkout with a declined card
Requirement: when the provider returns `declined`, the order stays unpaid, the inventory reservation is released, the customer sees a safe message and can retry with another card. This crosses UI, API, storage and integration boundaries.
Every expectation below can be observed. “The error is handled correctly” would hide the order state, money movement and reservation behavior.
Priority: High Requirement: PAY-AC-07 Preconditions: - user buyer_17 is signed in - cart has SKU-1842, qty=1 - inventory reservation TTL is 15 minutes Data: card token test_declined_01 1. Open checkout and submit the card Expected: button shows progress and cannot submit twice 2. Wait for POST /payments response Expected: 402; error.code=card_declined; no secret data 3. Open the order Expected: status=payment_failed; paid_at=NULL 4. Check inventory after the agreed processing time Expected: reservation released exactly once 5. Retry with test_approved_01 Expected: one successful charge; order=paid; one confirmation Evidence: request ids, provider stub log, order id, timestamps
Turn the same risk into a useful checklist
A checklist is not a damaged test case. It groups coverage and exposes the risk model. Each item still names an object and a rule, but it does not prescribe every click.
For checkout, group checks by order state, provider failure, retry, idempotency and timeout recovery. That reveals coverage far better than a diary of cursor movements.
[ ] declined: order is not paid; retry is available [ ] insufficient_funds: user message contains no provider internals [ ] timeout before response: status becomes known after reconciliation [ ] duplicate submit: one charge and one order transition [ ] callback repeated: inventory is released/confirmed once [ ] callback out of order: final state follows the agreed state machine [ ] refresh/back: no second payment request [ ] audit log: request id and transition are traceable
Positive, negative and boundary coverage
One happy path does not establish quality. Partition inputs into allowed and forbidden payment methods, values inside and outside limits, active and expired promotions, and provider results such as success, decline, timeout and malformed response. Then select representatives and boundaries.
A negative test checks the absence of a forbidden effect, not only an error code. After 422 no order is created; after 403 foreign data is unchanged; after timeout a retry cannot double-charge.
| Value | Expected | Purpose |
|---|---|---|
| 99 | 422; no payment | Below lower boundary |
| 100 | Accepted | Lower boundary |
| 101 | Accepted | Just inside |
| 99,999 | Accepted | Inside upper boundary |
| 100,000 | Accepted | Upper boundary |
| 100,001 | 422; no payment | Above upper boundary |
Test cases, checklists and bug reports answer different questions
A test case defines a check before execution. A checklist manages breadth. A bug report records an observed mismatch and its evidence. Copying an entire case into a defect is rarely useful; include only the setup and actions needed to reproduce the actual result.
Traceability matters more than the layout. Requirements connect to checks, runs to results, failures to defects, and fixes to retest plus nearby regression. Those links explain which rule the test protected.
| Artifact | Question | Output |
|---|---|---|
| Test case | How do we repeat this check? | Pass / Fail / Blocked |
| Checklist | Which risks must we not forget? | Marks and notes |
| Bug report | What violates an agreed rule? | Defect with evidence |
| Test report | What was tested and can we release? | Risk-based conclusion |
Review: seven signs of a strong check
Review the model, not the writer’s formatting preferences. Ask which risk is covered, where the expectation came from, whether data is reproducible and whether a product failure can be separated from an environment failure.
Tests need maintenance. When a contract changes, stale expected results create false alarms. Owners should remove duplicates, consolidate setup and preserve important decisions instead of only growing the count.
- Links to a current requirement or agreed rule.
- A title distinguishable from neighboring cases.
- Repeatable setup and data.
- Observable expected results without “works correctly”.
- Material side effects and forbidden changes are checked.
- Dependencies are removed or made explicit.
- Maintenance cost matches the protected risk.
Answer interview questions without reciting a template
Interviewers usually care about reasoning: can you connect documentation to context and risk? Give a one-sentence definition, state selection criteria and finish with a concrete example. When the process is team-specific, say so and propose a reasonable approach.
For “test a login form,” first clarify email and password rules, attempt limits, MFA, recovery, roles and session behavior. Then show partitions, boundaries, states and security checks. “Valid and invalid login” alone says little about coverage.
1. Definition: what the artifact is for 2. Context: risk, team and execution frequency 3. Choice: why test case, checklist or charter 4. Example: concrete data and observable expected result 5. Trade-off: coverage versus maintenance cost 6. Follow-up: what I would clarify before writing it
Frequently asked questions
Does every step need an expected result?
Only when an observable result appears. Do not repeat trivial navigation outcomes, but never hide an intermediate state that determines the final result.
Can test cases live in a spreadsheet?
Yes, if collaboration, history and reporting are sufficient. A TMS helps with runs, parameters, traceability and analytics; the tool itself does not make a case good.
Should every manual test case become an automated test?
No. Automation pays for stable, repeatable and important checks. Exploratory, visual or fast-changing scenarios may remain manual, and automated tests need not mirror manual steps exactly.
What belongs in expected results when requirements conflict?
Do not silently choose. Record the conflict, get a decision from the requirement owner and link the case to the agreed source. Until then, the check may be Blocked rather than Failed.
A good test case does not prove that its author can fill a form. It makes risk visible, execution reproducible and the result useful for a release decision.