Use Case Testing Explained | Basic, Alternative & Exception Flow Design + Playwright Implementation

test-automation

Use case testing is a test design technique that converts a user’s end-to-end operation flow — the sequence of actions a user takes to achieve a goal — into test scenarios. It’s especially effective for E2E test scenario design and for prioritizing regression testing.

💡 In one sentence
Use case testing = “Testing the entire sequence of actions a user takes to accomplish a goal”

Use case testing lets you convert “what users actually do” directly into test scenarios — catching the user-perspective bugs that slip through as “technically works, but unusable in practice.”

📌 Who This Article Is For

  • QA engineers and developers learning use case testing for the first time
  • Anyone struggling with how to design E2E test scenarios
  • Those who want a systematic approach to building user-perspective test cases
  • Engineers who want to apply use case testing to Playwright × pytest E2E test design

✅ What You’ll Learn

  • The concept behind use case testing and how to design basic, alternative, and exception flows
  • How to apply the technique to common production scenarios like purchase flows and user registration
  • How to convert use case designs into Playwright × pytest E2E tests

👤 About the Author

Written by Yoshi, a QA and test automation engineer with 15+ years of hands-on experience. Use case testing is a technique used daily for E2E test scenario design. Code is publicly available on GitHub: github.com/YOSHITSUGU728/automated-testing-portfolio

“All the unit tests pass, but the app breaks when you actually use it.” “We only tested the happy path, and a bug from a real user flow hit production.” — these problems stem from a lack of user-perspective test design.

  • Unit and functional tests alone can’t verify the full user operation flow
  • Only the basic flow (happy path) gets tested — alternative and exception flows are overlooked
  • Test scenarios are written from an engineer’s perspective, not a user’s — diverging from real usage

Use case testing solves these problems. This article covers everything from the concept, to designing scenarios, to implementing them as Playwright E2E tests.

📌 Key Takeaways

  • A test design technique that breaks a user’s goal-achieving flow into basic flow, alternative flows, and exception flows
  • Basic flow verifies the happy path · Alternative flows verify branching paths · Exception flows verify error handling
  • In Playwright × pytest, 1 use case = 1 test file is the recommended structure

What Is Use Case Testing?

Use case testing is a test design technique that converts “the sequence of actions a user takes to achieve a goal using the system (the use case)” into test scenarios.

For the use case “purchase a product,” the sequence is: log in → select item → add to cart → enter payment details → confirm order → view completion. Use case testing turns this sequence directly into test scenarios. Because it verifies the system from the user’s perspective, it finds bugs that only appear across the full flow — things unit tests will never catch.

AspectUnit / Functional TestingUse Case Testing
PerspectiveDeveloper / feature-by-featureUser / goal-by-goal
ScopeIndividual features, inputs/outputsFull operation flow, screen transitions
Bugs foundLogic bugsFlow, integration, UX bugs
Automation toolspytest · unittestPlaywright · Selenium

What’s the Difference Between Use Case Testing and State Transition Testing?

Both techniques deal with flows, but use case testing and state transition testing have different perspectives and goals. They’re easy to confuse in practice, so let’s clarify.

AspectUse Case TestingState Transition Testing
PerspectiveUser’s goal-achieving flowCorrectness of system states and transitions
What it verifiesBasic, alternative, and exception flowsValid transitions and invalid transitions
Best suited forUI-driven systems in generalStateful systems (e-commerce, reservations)
Typical use casesPurchase flow, user registration, searchOrder status management, login state

💡 Decision Guide

  • Want to verify “how many steps it takes a user to reach their goal?” → Use case testing
  • Want to verify “is this operation valid or invalid from this state?” → State transition testing
  • In production, both are used together — use case testing covers the happy path; state transition testing supplements it with invalid transition coverage.

What’s the Difference Between Use Case Testing and E2E Testing?

These two concepts are commonly confused, but they serve completely different roles.

AspectUse Case TestingE2E Testing
TypeA test design techniqueA test execution method
RoleDecides what to testThe means of how to run tests
ToolsDesign docs, spreadsheetsPlaywright · Selenium · Cypress
💡 How they relate: The standard production workflow is to design scenarios with use case testing, then implement them as E2E tests with Playwright. Writing E2E tests without a design first tends to produce test code where nobody is sure what’s actually being verified.

What Are the Core Components of Use Case Testing?

Use case testing is built on three flow types: the basic flow, alternative flows, and exception flows.

Flow TypeDescriptionExample (Purchase Flow)
Basic FlowThe most common happy path sequenceLog in → select item → add to cart → pay → complete
Alternative FlowsValid but takes a different pathGuest checkout (no login) · apply coupon · select different item when out of stock
Exception FlowsAn error or abnormal condition occursPayment declined · session expired · required field left empty
💡 Key Point: Most QA teams test only the basic flow (happy path). The real value of use case testing is surfacing alternative and exception flows. Ask “what about guest checkout?”, “what about coupons?”, “what if payment fails?” — and keep asking until you’ve mapped every branch.

📊 Use Case Flow Diagram: “Purchase a Product”

Basic
👤 Start
Login
Select Item
Add to Cart
Pay
🎯 Done

Alt
Apply Coupon
🎯 Done
← valid, different path

Exc
Payment Fails
🔄 Error
← error / abnormal

Basic flow (happy path)  
Alternative flow (valid, different path)  
Exception flow (error / abnormal)

Example ①: Test Design for a Purchase Use Case

Here’s the “purchase a product” use case for an e-commerce site, broken down into basic flow, alternative flows, and exception flows.

Basic Flow (Happy Path)

StepUser ActionSystem Response (What to Verify)
Step 1Log inDashboard is displayed
Step 2Search for and select a productProduct detail page is displayed
Step 3Add to cartCart badge count increases
Step 4Proceed to checkout from cartOrder confirmation page is displayed
Step 5Enter payment info and confirm orderOrder complete page shown and confirmation email sent

Alternative Flows (Valid, Different Path)

Alternative FlowTriggerWhat to Verify
Guest checkoutUser purchases without logging inGuest checkout flow completes correctly
Coupon appliedUser enters a coupon code for a discountDiscounted total is calculated correctly
Multiple itemsUser adds multiple items to cart and purchasesSubtotal and shipping are calculated correctly

Exception Flows (Error / Abnormal)

Exception FlowTriggerWhat to Verify
Payment declinedCredit card is rejectedError message shown and cart contents retained
Out of stock mid-checkoutItem goes out of stock during paymentAppropriate error shown and no double charge occurs
Session expiredSession expires on the payment screenRedirected to login page and cart is retained

Example ②: Test Design for a User Registration Use Case

Another common use case — “register as a member” — with all three flow types in a single table.

Flow TypeScenarioWhat to Verify
Basic FlowEnter email and password, complete registrationConfirmation email received and login works
Alternative ①Register via social login (Google / Apple)OAuth completes correctly and account is created
Alternative ②Register via invitation linkInvitation benefit is correctly applied to account
Exception ①Register with an already-registered email addressDuplicate registration error is shown
Exception ②Email confirmation link has expiredResend button is displayed

Applying Use Case Testing to Playwright × pytest

Scenarios designed with use case testing translate directly into Playwright × pytest E2E tests. The production best practice is 1 use case = 1 test file.

Folder Structure

tests/
├── conftest.py
└── e2e/
    ├── test_purchase.py        # Use case: Purchase a product
    ├── test_register.py        # Use case: Register as a member
    └── test_login.py           # Use case: Log in

test_purchase.py — E2E Tests for the Purchase Use Case

import pytest
from playwright.sync_api import Page, expect

# ── Basic Flow ───────────────────────────────────
def test_purchase_basic_flow(logged_in_page: Page):
    """Basic flow: logged-in user purchases a product"""
    # Step 2: Select product
    logged_in_page.goto("localhost:3000/products/1")
    expect(logged_in_page.locator("h1.product-title")).to_be_visible()

    # Step 3: Add to cart
    logged_in_page.click("#add-to-cart")
    expect(logged_in_page.locator(".cart-badge")).to_have_text("1")

    # Step 4: Proceed to checkout
    logged_in_page.goto("localhost:3000/cart")
    logged_in_page.click("#checkout-btn")

    # Step 5: Confirm order
    logged_in_page.fill("#card-number", "4111111111111111")
    logged_in_page.fill("#expiry", "12/26")
    logged_in_page.fill("#cvv", "123")
    logged_in_page.click("#confirm-order-btn")
    expect(logged_in_page.locator(".order-complete")).to_be_visible()

# ── Alternative Flow ─────────────────────────────
def test_purchase_with_coupon(logged_in_page: Page):
    """Alternative flow: purchase with coupon applied"""
    logged_in_page.goto("localhost:3000/cart")
    logged_in_page.fill("#coupon-input", "DISCOUNT10")
    logged_in_page.click("#apply-coupon-btn")
    # Verify the discounted amount is displayed
    expect(logged_in_page.locator(".discount-amount")).to_be_visible()

# ── Exception Flow ───────────────────────────────
def test_purchase_payment_failure(logged_in_page: Page):
    """Exception flow: error shown on payment failure, cart retained"""
    logged_in_page.goto("localhost:3000/cart")
    logged_in_page.click("#checkout-btn")
    # Pay with an invalid card number
    logged_in_page.fill("#card-number", "0000000000000000")
    logged_in_page.click("#confirm-order-btn")
    # Verify error message is shown
    expect(logged_in_page.locator(".payment-error")).to_be_visible()
    # Verify cart contents are retained
    expect(logged_in_page.locator(".cart-badge")).to_have_text("1")
💡 Pro Tip: Grouping basic, alternative, and exception flows in the same file creates a single source of truth — “all tests for the purchase use case are right here.” Naming test files after the use case they cover makes it immediately clear which scenarios are tested without opening the file.

⚠️ 4 Common Pitfalls in Use Case Testing

Here are the mistakes that are easy to make when designing use case tests in practice.

① Stopping at the basic flow (happy path)

Only verifying “the product can be purchased” and calling it done. The real value of use case testing is surfacing alternative and exception flows. Keep asking: “What about guest checkout?”, “What about coupons?”, “What if payment fails?” — until you’ve covered every branch.

② Cramming multiple use cases into a single test function

Writing “register → log in → purchase → log out” all inside one test function makes failures hard to pinpoint, and if an early step fails, all subsequent steps can’t run. Follow the 1 use case = 1 test function principle.

③ Writing scenarios from an engineer’s perspective, not a user’s

Scenarios written around “test the API parameters” or “check that it’s saved to the DB correctly” are functional tests, not use case tests. Use case testing starts from “how does the user interact with the screen?” Using user stories (“as a [user], I want to [action]”) as a reference when designing scenarios is an effective way to stay user-focused.

④ Treating all use cases as equally important

With many use cases, testing everything at the same frequency is unrealistic. Core use cases like “complete purchase” and “log in” should run every time; others like “change password” or “update address” can run weekly. Prioritizing by risk and usage frequency is what separates efficient QA from exhaustive-but-slow QA.

FAQ

Q. What types of systems benefit most from use case testing?

Any system with a UI that users interact with is a good candidate. Use case testing is most effective where multi-step operation flows exist — e-commerce (purchase, registration, search), reservation systems (search, book, modify, cancel), and internal business tools (submit, approve, reject) are all classic examples.

Q. How do I choose between use case testing and state transition testing?

Use case testing verifies the full sequence of steps a user takes to achieve a goal. State transition testing verifies that system states and their transitions are correct — and that invalid transitions are properly rejected. In practice both are often combined: use case testing covers the happy path, while state transition testing adds invalid transition coverage on top.

Q. How much does ISTQB cover use case testing?

ISTQB Foundation Level tests “the concept of use case testing and the definition of basic and alternative flows.” Understanding that “test cases derived from a use case include the basic flow, alternative flows, and exception flows” is enough to handle the exam questions.

In production, a common workflow is to extract use cases from user stories (“as a [user], I want to [action]”) or product requirements, then convert them into Playwright × pytest E2E tests. Because the design document and test code map one-to-one, it’s immediately clear which tests need updating when features are added or changed.

📋 Summary

  • Use case testing is a test design technique for mapping a user’s goal-achieving operation flow
  • Covering basic flow, alternative flows, and exception flows gives you systematic coverage from happy path to error cases
  • The biggest value is surfacing alternative and exception flows — keep asking “what about guest checkout?”, “what if payment fails?”
  • 1 use case = 1 test file is the recommended Playwright × pytest implementation structure
  • Prioritize by risk and usage frequency — not all use cases need to run at the same cadence

The greatest value of use case testing is starting from “what users actually do” — systematically uncovering cross-flow bugs that unit tests will never find. Start by writing out the basic, alternative, and exception flows for a “purchase a product” or “register an account” use case in a service you already work on.

Copied title and URL