Free Ebook cover Test Case Design for Beginners: From User Stories to Clear Test Scenarios

Test Case Design for Beginners: From User Stories to Clear Test Scenarios

New course

8 pages

Quality Review: Making Test Cases Unambiguous and Maintainable

Capítulo 8

Estimated reading time: 9 minutes

+ Exercise

What “Quality Review” Means for Test Cases

A quality review is a deliberate check that each test case can be read, executed, and maintained by someone other than the author—without guessing. The goal is to remove ambiguity, hidden assumptions, and fragile dependencies so results are trustworthy and failures are diagnosable.

In practice, quality review answers four questions: (1) Is it clear? (2) Is it testable? (3) Is it independent? (4) Is it observable?

Review Checklist (Use This Every Time)

1) Clarity

  • Single intent: The test verifies one main behavior (not multiple unrelated outcomes).
  • Unambiguous wording: No “should work”, “correctly”, “as expected”, “fast”, “properly”. Replace with measurable outcomes.
  • Consistent terminology: Uses the same names as the product UI, API fields, and acceptance criteria (e.g., “Email address” vs “User email”).
  • Explicit preconditions: State required user state, permissions, feature flags, and data setup.
  • Explicit data: Inputs are concrete (example values), or clearly parameterized with constraints.

2) Testability

  • Executable steps: Each step is an action a tester can perform (or an automation can run) without interpretation.
  • Deterministic expected results: Expected results are specific and verifiable; avoid subjective checks.
  • Clear pass/fail criteria: A reader can decide pass/fail from the expected results alone.
  • Appropriate level: The test case matches the intended level (UI vs API vs integration) and doesn’t mix levels without stating it.

3) Independence

  • No hidden ordering: The test does not require another test to run first.
  • Self-contained setup: Any required entities (user, account, cart, record) are created or clearly referenced as stable fixtures.
  • Safe cleanup: If the test creates data, it either cleans up or uses disposable data that won’t pollute future runs.
  • No shared mutable state: Avoid relying on “the last created item”, “the newest email”, “the current time” unless controlled.

4) Observability

  • Visible evidence: The test specifies what to observe: UI message text, status code, database record, audit log entry, email content, etc.
  • Failure diagnostics: The test indicates where to look when it fails (e.g., “check error banner”, “verify response body field X”).
  • Stable assertions: Avoid asserting volatile elements (timestamps, random IDs) unless you assert format/pattern or capture values.

Practical Review Workflow (Step-by-Step)

Step 1: Read the test case “cold”

Read it as if you have never seen the feature. If you have to ask “What does that mean?” or “Where do I find that?”, the test is unclear.

Step 2: Highlight nouns and verify terminology

Circle key terms (roles, screens, fields, statuses). Ensure they match the product and acceptance criteria exactly. Replace synonyms with the canonical term.

Step 3: Convert vague expectations into observable checks

Rewrite each expected result so it includes: what is observed, where it is observed, and the exact expected value or rule.

Continue in our app.

You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.

Or continue reading below...
Download App

Download the app

Step 4: Check independence and data control

Ask: “Can I run this test alone, on a fresh environment, at any time of day?” If not, add setup steps, stable fixtures, or explicit environment requirements.

Step 5: Split combined assertions

If one test verifies multiple behaviors, split into separate tests or separate clearly labeled checks only when they are tightly coupled and always fail together.

Step 6: Validate against acceptance criteria

Map each test to the relevant acceptance criteria and confirm: (a) it actually verifies the criterion, and (b) it doesn’t invent extra requirements.

Common Issues and How to Fix Them

Issue 1: Combined assertions (too much in one test)

Problem: A single test checks multiple outcomes that can fail independently, making failures hard to diagnose and maintenance harder.

Before (problematic):

Steps: Submit the registration form with valid data. Expected: Account is created, user is logged in, welcome email is sent, and profile page shows correct name.

Fix options:

  • Split by behavior: Create separate tests: “Account creation”, “Auto-login after registration”, “Welcome email sent”, “Profile shows name”.
  • Keep together only if inseparable: If the product defines them as one atomic outcome, keep them but list expected results as separate, observable bullets and ensure diagnostics are clear.

After (split example):

TC-REG-01 Account is created with valid registration data Expected: User record exists; confirmation message displayed; user can log in with created credentials.

Issue 2: Unclear expected results

Problem: “Error is shown” or “System prevents submission” does not specify what to observe.

Before:

Expected: An error is shown for invalid password.

After:

Expected: Password field shows validation message “Password must be at least 12 characters” and the Submit button remains disabled.

Tip: If exact wording is unstable, assert a stable identifier (error code) or a rule-based pattern (e.g., “message mentions minimum length 12”).

Issue 3: Missing data details

Problem: “Enter valid data” forces the executor to invent inputs, causing inconsistent results.

Fix: Provide concrete values or a data table/parameter definition.

Input data: Email = alex.tester+01@example.com Password = P@ssw0rd!P@ssw0rd! Country = US

Also check: Are there constraints (unique email, allowed domains, required formats) that must be stated?

Issue 4: Environment assumptions

Problem: Test silently depends on configuration (feature flags, seeded data, third-party sandbox, locale, time zone).

Fix: Make assumptions explicit as preconditions and provide a fallback if possible.

Preconditions: Feature flag “NewCheckout” = ON Test environment has payment sandbox enabled Locale = en-US Time zone = UTC

Better: If the test can set the configuration itself (via admin UI/API), include that as setup to reduce reliance on external state.

Issue 5: Inconsistent terminology

Problem: Using different names for the same thing creates confusion and traceability gaps.

Fix: Standardize terms and add a short glossary in the test suite if needed.

  • Use “Customer” everywhere (not “User” in some tests and “Client” in others) if the product uses “Customer”.
  • Match UI labels exactly when referencing buttons/fields (e.g., “Sign in” vs “Login”).

Issue 6: Steps that hide multiple actions

Problem: “Create an order” could mean many steps and different paths.

Fix: Expand into explicit actions or reference a stable helper procedure/fixture with a clear name and version.

Setup: Create order via API using fixture ORDER_STANDARD_01 (1 item, in-stock, shipping required). Record orderId.

Issue 7: Non-observable outcomes

Problem: The test expects something that cannot be verified at the chosen level (e.g., “data is encrypted” via UI-only test).

Fix: Change the observation method (logs, API response, database, security tooling) or rewrite the test to verify an observable proxy (e.g., “password is not returned in any response”).

Peer-Review Techniques That Catch Real Problems

Technique 1: Read tests as a script (role-play execution)

One reviewer reads the test steps out loud; another person “executes” mentally and interrupts whenever something is unclear. Capture every question as a defect in the test case, not as a “reviewer misunderstanding”.

  • Ask: “Where exactly do I click?”
  • Ask: “What data do I use?”
  • Ask: “How do I know it passed?”

Technique 2: Challenge each step (“Why is this here?”)

For every step, the reviewer asks:

  • Purpose: Does this step contribute to the intent?
  • Necessity: Can it be removed without losing coverage?
  • Risk: Does it introduce flakiness (timing, external dependency, shared state)?

This often reveals redundant navigation, unnecessary UI steps for an API-level test, or setup that belongs in a fixture.

Technique 3: Validate alignment with acceptance criteria

Reviewers check that each test case maps to a specific acceptance criterion and that the expected results reflect the criterion’s wording and rules.

  • If a test covers multiple criteria, confirm that is intentional and still maintainable.
  • If a criterion has multiple rule combinations, ensure the suite covers them without gaps.

Technique 4: “Failure story” review

Ask: “If this test fails, what will we learn?” A good test failure points to a likely cause area (validation, permissions, calculation, integration) and provides evidence (message, field, response, log reference).

Capstone Task: Refine a Small Test Suite (Quality + Coverage Balance)

Scenario: You are given a small test suite for a “Promo Code” feature in checkout. The suite has quality issues and uneven coverage. Your task is to rewrite and reorganize it so it becomes unambiguous, maintainable, and traceable.

Starting suite (intentionally flawed)

TC1 Apply promo code Expected: discount applied TC2 Apply invalid promo Expected: error TC3 Apply promo then remove it Expected: works TC4 Promo code should not work for excluded items TC5 Check totals are correct

Your refinement steps

Step 1: Create a review log

For each test, list issues under: clarity, testability, independence, observability. Example entries:

  • “discount applied” is not observable (which field changes? by how much?).
  • Missing data: which promo code? which cart contents? which currency?
  • “works” is ambiguous.
  • “totals are correct” combines multiple assertions without specifying calculation rules.

Step 2: Normalize terminology and define fixtures

Define consistent names for cart types and promo codes. Example fixtures (adapt to your system):

Fixture CART_A: 1x ItemRegular price 100.00 eligible for promos Fixture CART_B: 1x ItemExcluded price 50.00 excluded from promos Fixture PROMO10: 10% off eligible items, max uses not exceeded Fixture PROMOEXPIRED: expired promo Fixture PROMOMIN200: requires subtotal >= 200.00

Step 3: Rewrite each test with explicit expected results

Ensure each test has concrete inputs and observable outputs (UI fields, totals, messages, applied promo indicator). Split combined assertions where needed.

TC-PROMO-01 Apply valid percentage promo to eligible cart Preconditions: CART_A loaded, currency USD Steps: Enter code PROMO10 and apply Expected: Promo banner shows PROMO10 as applied Discount line shows “Promo discount” = 10.00 Subtotal remains 100.00 Total decreases by 10.00

Step 4: Balance positive/negative coverage

Check you have both successful and failing applications, and that failures specify exact messages/behaviors (e.g., no discount line added, promo not listed as applied).

  • Positive: valid promo applies to eligible items.
  • Negative: invalid code, expired code, unmet minimum, excluded items.

Step 5: Add boundary and equivalence-focused cases (without duplicating earlier learning)

Ensure the suite includes representative edges and typical groups, expressed as concrete tests. Examples to include in your refined suite:

  • Minimum subtotal boundary: subtotal exactly at threshold vs just below.
  • Promo length/format boundary if applicable (e.g., max characters) with clear expected validation.
  • Equivalence groups for promo status: valid/invalid/expired; eligible/ineligible cart.

Step 6: Decision-table rule coverage check

List the key conditions and outcomes for promo application and ensure each rule is represented by at least one test. Example conditions:

  • Code validity (valid/invalid/expired)
  • Cart eligibility (eligible items present? excluded-only?)
  • Minimum subtotal met (yes/no)

Then verify your suite covers each meaningful combination your product supports (avoid impossible combinations).

Step 7: Add traceability links

For each refined test, add references to the relevant acceptance criteria IDs (or requirement IDs) and the scenario ID used in your project. Ensure every acceptance criterion has at least one linked test and that no test is “orphaned”.

Traceability example: TC-PROMO-01 links to AC-PROMO-1, AC-PROMO-3 TC-PROMO-04 links to AC-PROMO-2 (excluded items) TC-PROMO-06 links to AC-PROMO-4 (minimum subtotal)

Deliverable

Submit a refined promo-code test suite containing:

  • Clear, executable tests with observable expected results
  • Independent setup using named fixtures or explicit data creation
  • Balanced positive and negative tests
  • Coverage for boundaries and representative equivalence groups
  • Rule coverage aligned to your decision-table conditions
  • Traceability links for every test case

Now answer the exercise about the content:

During a quality review, which change best turns a vague expected result into an observable, verifiable check?

You are right! Congratulations, now go to the next page

You missed! Try again.

Observable expected results state what to check, where to check it, and the exact value or rule. Vague phrases like “error is shown” are ambiguous and make pass/fail decisions harder.

Download the app to earn free Certification and listen to the courses in the background, even with the screen off.