BootcampCapstone · Deliverable 2

Test-case suite for the promo-code & checkout flow

Builds on Topic 5.

What you'll produce

A structured suite of 12–15 test cases for ShopSphere's new checkout-and-promo-code flow — each with a stable ID, a clear title, preconditions, exact numbered steps, and a single observable expected result — covering the happy path, edge cases, and error/negative cases. This is the executable spec a tester re-runs every release: it turns the requirements spec into repeatable checks, lets anyone on the team get the same result you do, and produces an auditable record of exactly what was verified before sign-off. It's the artifact that distinguishes a real QA engineer from someone who "clicks around" — and the one a hiring manager will read most closely in your portfolio, because it shows whether you can think systematically about coverage instead of only testing the happy path. You'll format it as it would live in TestRail or a shared spreadsheet, so it drops straight into a real team's workflow.

Instructions

  1. Anchor to the spec and to Deliverable 1. Pull the in-scope items from your test plan: the promo-code field, cart subtotal / quantity, guest checkout, Apple Pay, and order placement. You'll write cases against these — not against random screens. If your plan marked Apple Pay as a thin smoke-only slice, keep it to one or two cases here.
  2. Reuse the canonical test data, don't invent your own. The promo codes and their rules are fixed in the Capstone fixtures so every deliverable agrees: SAVE20 = 20% off, min cart $20.00, multi-use; WELCOME15 = $15.00 off, single-use per account, min cart $50.00; SUMMER19 = expired 2026-05-31; SUMMER20 = case-insensitive alias of SAVE20. Restate them in a short Test data block at the top of your suite so a reviewer can reproduce every case without leaving the document.
  3. Choose a fixed column structure and keep it identical for every case: ID · Title · Type (Positive / Negative / Edge) · Priority (P1–P3) · Preconditions · Steps (numbered) · Expected result. Consistency is what makes a suite feel like a paid product.
  4. Write IDs that sort and group, e.g. TC-PROMO-01, TC-CART-03, TC-GUEST-01, TC-PAY-01. A tester scanning the run should know the feature area from the ID alone.
  5. Cover the three buckets deliberately, not by accident:
    • Happy path (positive): valid code applies correct discount; order totals update; guest checkout completes; Apple Pay path succeeds.
    • Edge cases: minimum-cart boundary (just below vs. just at the threshold), case-insensitivity, applying then removing a code, re-applying a single-use code, recalculation when cart quantity changes after a code is applied.
    • Error / negative cases: invalid code, expired code, empty submission, leading/trailing whitespace, attempting two codes, a code below the minimum cart value.
  6. Write atomic steps and a single, observable expected result. Each step is one action ("4. Enter SAVE20 in the Promo code field and click Apply."). The expected result must be something a tester can see — an exact amount, an exact error string, a specific UI state — not "it works." Prefer real numbers: a $48.00 subtotal with SAVE20 becomes $38.40, not "discount applied."
  7. Pin every expected money value to the math so the case is falsifiable. State the subtotal, the discount, and the resulting total explicitly; that's what lets the case catch a rounding or off-by-one bug instead of waving at it.
  8. Make negative cases specify the exact failure, including the message text and that nothing partially applies (no discount, no charge, cart unchanged). "Shows an error" is not gradeable; "Shows inline error 'This code has expired' and the order total is unchanged at $62.00" is.
  9. Add a priority to each case (P1 = blocks release if it fails, e.g. wrong discount math or a code that lets a free order through; P3 = cosmetic) so the suite doubles as a run order under time pressure.
  10. Self-review for the traps: every case independently runnable from its preconditions, no two cases that are secretly the same equivalence class, at least one boundary pair, and at least one case proving a security-relevant rule (single-use enforcement or stacking prevention). Then format the whole thing as a clean table.

Worked example

(Feature: ShopSphere redesigned checkout + promo-code field. Build 2.4.0-rc3 on https://staging.shopsphere.com, Chrome 126 / macOS 14, plus iOS 17 Safari for the Apple Pay case. Currency: USD. All values from the shared Capstone fixtures.)

Test data (the canonical promo codes — see Capstone fixtures)

CodeEffectRules
SAVE2020% off subtotalMin cart $20.00, multi-use, not stackable
WELCOME15$15.00 offMin cart $50.00, single-use per account
SUMMER1920% offExpired 2026-05-31
SUMMER20alias of SAVE20code entry is case-insensitive

Standard cart for examples: 3 × "Aurora Desk Lamp" @ $16.00 = subtotal $48.00, shipping $0.00 (free over $35), unless a case says otherwise.

IDTitleTypePriPreconditionsStepsExpected result
TC-PROMO-01Valid percentage code applies correct discountPositiveP1Logged-in shopper; cart subtotal $48.00; no code applied1. Open cart and click Checkout. 2. On the checkout page locate the Promo code field. 3. Enter SAVE20. 4. Click Apply.Discount line shows −$9.60 ("20% off — SAVE20"); order total updates from $48.00 to $38.40; success message "Promo code applied" appears.
TC-PROMO-02Code entry is case-insensitiveEdgeP2As TC-PROMO-011. Go to checkout. 2. In Promo code enter summer20 (lowercase alias). 3. Click Apply.Treated as SAVE20: discount −$9.60, total $38.40. Code is accepted regardless of letter case.
TC-PROMO-03Leading/trailing whitespace is trimmedEdgeP3As TC-PROMO-011. Go to checkout. 2. Enter " SAVE20 " (spaces before and after). 3. Click Apply.Whitespace is trimmed; code applies normally (−$9.60, total $38.40). It is not rejected as an unknown code.
TC-PROMO-04Invalid code is rejectedNegativeP1As TC-PROMO-011. Go to checkout. 2. Enter FAKE99. 3. Click Apply.Inline error "Invalid promo code"; no discount line appears; order total unchanged at $48.00; field retains focus for re-entry.
TC-PROMO-05Expired code is rejected with a specific messageNegativeP1As TC-PROMO-01; system date 2026-06-151. Go to checkout. 2. Enter SUMMER19. 3. Click Apply.Inline error "This code has expired" (distinct from "Invalid promo code"); no discount; total unchanged at $48.00.
TC-PROMO-06Empty submission is handledNegativeP2As TC-PROMO-011. Go to checkout. 2. Leave Promo code blank. 3. Click Apply.Inline message "Enter a promo code"; no network error/spinner hangs; total unchanged at $48.00.
TC-PROMO-07Code below minimum cart value is blocked at the boundaryEdgeP1Cart subtotal set to $19.99 (one lamp @ $16.00 + one @ $3.99 add-on); no code applied1. Go to checkout (subtotal $19.99). 2. Enter SAVE20 (min cart $20.00). 3. Click Apply.Rejected with "Add $0.01 more to use this code (minimum $20.00)"; no discount; total stays $19.99. (Boundary partner of TC-PROMO-08.)
TC-PROMO-08Code applies exactly at the minimum thresholdEdgeP1Cart subtotal set to $20.00; no code applied1. Go to checkout (subtotal $20.00). 2. Enter SAVE20. 3. Click Apply.Code is accepted at the boundary: discount −$4.00, total $16.00. (Proves the rule is "≥ $20.00", not "> $20.00".)
TC-PROMO-09Discount recalculates when cart quantity changes after applyEdgeP1TC-PROMO-01 completed: SAVE20 applied, total $38.401. Return to cart. 2. Change lamp quantity from 3 to 5 (subtotal $80.00). 3. Return to checkout.Discount recalculates to −$16.00 (20% of $80.00); total becomes $64.00. The discount is not stale at −$9.60.
TC-PROMO-10Applied code can be removedPositiveP2TC-PROMO-01 completed: SAVE20 applied, total $38.401. On checkout, click Remove next to the applied code.Discount line disappears; total reverts to $48.00; Promo code field is empty and ready for a new code.
TC-PROMO-11Applying a second code replaces the first, never stacksNegativeP1SAVE20 applied to the $48.00 cart (one discount line −$9.60, total $38.40)1. With SAVE20 already applied, enter WELCOME15 in the Promo code field. 2. Click Apply.Per the spec's no-stacking rule, the new code replaces the old one: the SAVE20 −$9.60 line is gone and a single WELCOME15 −$15.00 line remains; order total is exactly $33.00 ($48.00 − $15.00); banner reads "WELCOME15 applied — SAVE20 removed". Exactly one discount line is present; the stacked total $23.40 ($48.00 − $9.60 − $15.00) must never appear.
TC-PROMO-12Single-use code is rejected on second useNegativeP1Account has already redeemed WELCOME15 on a prior order; current subtotal $60.001. Go to checkout. 2. Enter WELCOME15. 3. Click Apply.Inline error "This code has already been used"; no $15.00 discount; total stays $60.00. (Security-relevant: prevents repeat redemption of a per-account code.)
TC-GUEST-01Guest checkout completes with a valid codePositiveP1Not logged in; cart subtotal $48.001. From cart click Checkout. 2. Choose Continue as guest. 3. Enter email guest@example.com and a valid shipping address. 4. Apply SAVE20. 5. Enter test card 4242 4242 4242 4242, exp 12/29, CVC 123. 6. Click Place order.Order is placed as guest; discount −$9.60 reflected; charged $38.40; confirmation page shows an order number and the email; no account-login required.
TC-GUEST-02Guest checkout blocks invalid email before paymentNegativeP2Not logged in; cart $48.001. Checkout → Continue as guest. 2. Enter email guest@@example (malformed). 3. Click Continue to payment.Inline error "Enter a valid email address"; the flow does not advance to the payment step; no charge attempted.
TC-PAY-01Apple Pay path completes with the discounted total (smoke)PositiveP1iOS 17 Safari; Apple Pay test card configured; cart $48.00; SAVE20 applied1. Go to checkout (total $38.40). 2. Tap Apple Pay. 3. Authenticate in the Apple Pay sheet (Face ID / passcode).Apple Pay sheet shows $38.40 (the discounted total, not $48.00); on authentication the order is placed and the confirmation page shows the order number.

Why these and not others: TC-PROMO-07/08 are a deliberate boundary pair (Topic 7 — the rule is "≥ $20.00", and off-by-one bugs live exactly there). TC-PROMO-01 alone stands in for the whole "valid in-range subtotal" equivalence class, so there's no TC for $30, $40, $48 separately. TC-PROMO-11/12 exist because a promo system that lets codes stack or single-use codes repeat is a revenue bug, not a cosmetic one — those are the P1s a release can't ship over. Note that TC-PROMO-11 asserts one designed outcome (replace → exact total $33.00 → exact banner), not "either replaces or errors": an either/or expected result can't be marked Pass/Fail, so it would violate the same one-observable-result rule this suite teaches. When a real spec says "not stackable" it has chosen one behavior; the test pins that choice (here: the documented rule that a new code replaces the current one) and also names the forbidden stacked total $23.40 so the case catches a silent regression into stacking. Apple Pay is one smoke case by design, matching the plan's thin slice for it.

Rubric

The app's AI scores the learner's submission against these criteria and gives feedback. Levels: Needs work (1) / Solid (2) / Excellent (3). Passing = every criterion at Solid or above.

  • Structure & runnability of each case — 1: missing IDs, preconditions, or expected results; steps too vague to follow · 2: every case has ID, title, preconditions, numbered atomic steps, and one expected result · 3: consistent columns, stable grouped IDs, shared documented test data, and each case is independently runnable from its preconditions by anyone.
  • Coverage across happy / edge / negative — 1: mostly happy-path; few or no negative cases · 2: 12–15 cases spanning all three buckets across the in-scope areas · 3: each bucket is deliberate and non-redundant — includes a boundary pair, case-insensitivity, recalculation-after-change, and security-relevant rules (single-use, no-stacking).
  • Falsifiable expected results — 1: "it works" / "shows an error" with no specifics · 2: concrete states and amounts given · 3: every money value pinned to explicit math (subtotal → discount → total) and every error names the exact message and confirms nothing partially applies — so each case can actually catch a bug.
  • Prioritization & QA judgment — 1: no priorities, or priorities don't reflect risk · 2: each case carries a sensible P1–P3 · 3: priorities map to release risk (discount-math and redemption-abuse cases are P1, cosmetics P3) and the suite reads as a defensible run order under deadline.
  • Coherence with the test plan (Deliverable 1) — 1: tests areas the plan excluded or ignores its priorities · 2: scope matches the plan · 3: clearly traces from the plan's in-scope items and risk ranking (e.g., Apple Pay kept to the plan's thin smoke slice), forming one continuous QA story.