Use Case Testing
Derive test cases from use case flows. Test what real users actually do — the happy path, alternate routes, and the things that go wrong.
1 The Hook
A team building an online booking tool for a NZ vet clinic tests the obvious thing: a customer picks a pet, picks a time, confirms the appointment. It works. Demo looks great. Ship it.
Then real customers arrive. One tries to book when the clinic is fully booked — the system lets them, double-booking a slot. Another has their internet drop mid-booking and comes back to find the appointment half-created. A third tries to book for two pets in one visit, which the form silently mangles. None of these were tested, because the team only tested the one path where everything goes right.
The defects were never in the happy path. They were in the alternate routes (two pets, a different time) and the exception routes (clinic full, connection lost) — the paths real users actually hit. Testing only the success path is testing the demo, not the product. A use case is not one line; it is a tree of flows, and the bugs live on the branches nobody walked.
2 The Rule
Every use case has three kinds of flow — the basic (happy) path, the valid alternate paths, and the exception paths where things go wrong — and you must derive test cases from all three, because real defects cluster on the alternate and exception branches the happy path never touches.
3 The Analogy
Planning a tramp on a Great Walk.
A sensible tramper on the Routeburn does not just plan the main track in good weather. They plan the main route (the basic flow), the alternate routes if a side track is the better option that day (alternate flows), and what to do if the river is up, the weather turns, or someone rolls an ankle (exception flows). The trampers who only plan the sunny-day main-track version are the ones the rescue helicopter goes looking for.
Use case testing is planning all the routes, not just the postcard one. The basic flow is the marked track on a fine day; the alternate flows are the valid detours; the exception flows are the river-in-flood, gear-failed contingencies. A use case test set that only covers the happy path is a tramp plan with no contingency — fine until something goes wrong, which it always does.
What it is
Use case testing treats the system from the user’s perspective. A use case describes a goal-driven interaction: who is doing it, what they want, and the sequence of steps to get there. Test cases are derived directly from these flows.
This technique is particularly valuable for integration and system testing — it tests how components interact to deliver user value, not just whether individual functions work.
The three flows
- Basic flow (happy path) — the most common, successful path through the use case. Test this first.
- Alternate flows — valid variations. A user pays with a different payment method; they log in via SSO instead of email/password.
- Exception flows — things that go wrong. Invalid data, timeout, payment declined, system unavailable. These flows matter as much as the happy path.
Worked example: checkout flow
| Flow type | Scenario | Test focus |
|---|---|---|
| Basic flow | User adds item, enters card details, completes purchase | Order confirmed, stock decremented, email sent |
| Alternate | User pays with saved card | Pre-filled payment, one-click confirm |
| Alternate | User applies discount code | Total recalculated, code validated |
| Exception | Card declined | Error message shown, order NOT created, no charge |
| Exception | Item goes out of stock during checkout | User informed, offered alternatives |
| Exception | Session times out mid-checkout | Cart preserved, user returned to checkout on login |
User stories vs use cases
In Agile teams, use cases are often replaced by user stories. The technique is the same — derive tests from the story’s acceptance criteria, happy path, and edge cases. ISTQB calls this user story testing, and it’s covered in the Agile Tester extension (CTFL-AT).
Good practice: for every user story, write at least one test for the basic flow, one for the most important alternate flow, and one for the most dangerous exception flow. Three tests minimum, derived directly from the story.
ISTQB mapping
| Ref | Topic | Level |
|---|---|---|
| 4.2.5 | Use Case Testing | CTFL Foundation |
| CTFL-AT | User Story Testing (Agile extension) | Foundation Agile |
Practice this technique: Try Junior Practice 10 — Multi-step form flow, Junior Practice 03 — GST & cart calculation.
4 Now You Try
Three graded exercises — spot, fix, then build. Write your answer, run it for AI feedback, then compare to the model answer.
For a MetService weather-alert sign-up use case, classify each scenario below as basic flow, alternate flow, or exception flow, and give a one-line reason for each.
Show model answer
a) Email + region + confirm → subscription created — BASIC FLOW. The primary success path; test this first. b) Sign up via RealMe instead of email — ALTERNATE FLOW. A valid variation in how the user achieves the same goal; it still succeeds. c) Email already subscribed → "already signed up" — EXCEPTION FLOW. A condition that prevents the normal completion; must be handled gracefully (no duplicate, clear message). d) Notification service down → error shown — EXCEPTION FLOW. An external dependency failure; verify the user is told and no partial subscription is left behind. e) "All regions" instead of one — ALTERNATE FLOW. A valid input variation that still completes successfully, just with different data. The rule of thumb: basic = the main success path; alternate = a different but valid way to succeed; exception = something goes wrong and the goal cannot be met normally.
A tester wrote the test set below for a "transfer money between accounts" use case in a NZ banking app. It only covers happy paths and misses entire flow types. Rewrite it so it covers the basic flow plus at least one alternate and at least two exception flows.
TC1 — Transfer $50 between two of your own accounts — succeeds
TC2 — Transfer $100 between two of your own accounts — succeeds
TC3 — Transfer $200 between two of your own accounts — succeeds
Rewrite with full flow coverage:
Show model answer
Test set with full flow coverage: Basic flow: - Transfer a valid amount between two of your own accounts with sufficient funds — succeeds, both balances update, confirmation shown. Alternate flow: - Transfer to a saved payee (someone else's account) instead of your own — succeeds via a slightly different confirmation step. Exception flow 1: - Transfer more than the available balance — rejected, clear "insufficient funds" message, no money moved. Exception flow 2: - Connection drops after pressing confirm — verify the transfer is either fully completed or not done at all (no money debited without being credited), and the user sees an accurate status on return. What was wrong with the original set: - All three tests are the same flow with a different number — that is one flow tested three times, not three flows. It is closer to (weak) equivalence/boundary testing on the amount than use case testing. - It covers zero alternate flows (e.g. paying a third party, scheduling a future transfer). - It covers zero exception flows (insufficient funds, daily limit exceeded, dropped connection, invalid account number) — and exception flows are where the dangerous money-handling bugs live.
A NZ public library lets members reserve a book online and collect it from a chosen branch. Derive a use case test set: write one basic flow, two alternate flows, and three exception flows, with the expected result for each.
Show model answer
Use case: reserve a book online and collect from a chosen branch. Basic flow: - Member logs in, searches a title that is in stock, reserves it, picks their local branch — reservation confirmed, hold placed, member notified when ready. Alternate flows: - The chosen title is on loan, so the member joins the hold queue instead of getting an immediate reservation — confirmed with an estimated wait position. - The member collects from a different branch than their usual one (inter-branch transfer) — reservation succeeds, with a note that transfer may add a day or two. Exception flows: - The member has unpaid fines above the borrowing threshold — reservation blocked, clear message explaining why and how to pay. - The member already has the maximum number of items reserved — reservation refused with the limit explained. - The reserved book is reported lost/withdrawn before collection — member notified, reservation cancelled, alternative copies or titles suggested. A senior would test that an expired reservation that was never collected is released back to the shelf (a time-based exception flow), and that the "notify when ready" step actually fires.
Self-Check
Click each question to reveal the answer.
Q1: Why is testing only the happy path of a use case effectively "testing the demo, not the product"?
Because real defects cluster on the alternate and exception branches — the paths real users actually hit when they do something valid-but-different or when something goes wrong. The happy path is the path everyone designed for; the branches nobody walked are where the bugs are.
Q2: What is the difference between an alternate flow and an exception flow?
An alternate flow is a valid, different way the user still achieves the goal (paying with a different method, choosing a different option) — it succeeds. An exception flow is where something goes wrong and the goal cannot be met normally (declined payment, timeout, blocked by a rule) — it must be handled gracefully rather than left to fail silently.
Q3: Why is use case testing especially valuable for integration and system testing?
Because it tests how components interact to deliver user value end to end, not just whether individual functions work in isolation. A use case crosses module boundaries (payment, stock, notification), so testing the flow exercises the integrations a unit test would never touch.
Q4: In agile teams, what replaces the formal use case, and is the technique any different?
User stories replace use cases, and ISTQB calls deriving tests from them user story testing (covered in CTFL-AT). The technique is the same: derive tests from the story's acceptance criteria, its happy path, its valid variations, and its edge/exception cases.
Q5: What is the minimum sensible test coverage for a single user story?
At least one test for the basic flow, one for the most important alternate flow, and one for the most dangerous exception flow — three tests minimum, all derived directly from the story. Anything less leaves a whole class of behaviour untested.
Try It — Classify the flows
A NZ government services portal lets citizens renew their driver licence online. Six test scenarios are listed below. Classify each as Basic flow, Alternate flow, or Exception flow.
| Scenario | Your classification |
|---|---|
| User logs in with RealMe, passes vision check, pays $49.10, licence renewed successfully | |
| User logs in with RealMe, but their licence has already expired more than 1 year ago — portal blocks renewal and directs them to NZTA | |
| User pays using credit card instead of internet banking | |
| Payment gateway times out — user session preserved, error displayed, no charge made | |
| User has an address outside Auckland, Wellington, and Christchurch — selects NZ Post rural delivery option | |
| RealMe identity verification fails — user cannot proceed, shown support contact |
Answers
| Scenario | Flow type | Why |
|---|---|---|
| RealMe login → vision check → pay → renewed | Basic flow | The primary success path. Test this first. |
| Licence expired >1 year — blocked | Exception flow | A system rule prevents completion. Dangerous if not handled — user is told nothing actionable. |
| Pays by credit card instead of internet banking | Alternate flow | A valid variation in payment method. Still succeeds, just differently. |
| Payment gateway timeout | Exception flow | External dependency failure. Must verify no double-charge and session recovery. |
| Rural NZ delivery option | Alternate flow | Valid path, different delivery address logic. Common NZ edge case. |
| RealMe verification fails | Exception flow | Identity provider error. Must not silently fail — user needs clear guidance. |