Q5 of 38 · Test design

What is state transition testing?

Test designJuniorstate-transitionfsmtest-designjunior

Short answer

Short answer: State transition testing models a feature as a finite-state machine — states the system can be in and the events that move it between them — then derives test cases from valid and invalid transitions.

Detail

State transition is the right technique when behaviour depends on history. A login form has states: logged out → logging in → logged in → locked out. A checkout flow has cart → checkout → payment → confirmation. Bugs in such systems usually involve transitions: forgetting to handle a state, allowing an invalid transition, or losing data on a transition.

The technique:

  1. Draw the state diagram — states as nodes, transitions as labelled arrows. Include the starting state and any terminal states.
  2. Identify valid transitions — for each state, which events move you to which next state, and what side effects occur.
  3. Identify invalid transitions — what shouldn't be allowed (e.g. paying before logging in). The system should refuse these gracefully.
  4. Derive test cases — at minimum: every state visited at least once (state coverage), every transition exercised at least once (transition coverage), and key invalid transitions explicitly tested.

Worked example for a simple subscription system. States: Trial → Active → Cancelled → Expired. Valid transitions include Trial→Active (user pays), Active→Cancelled (user cancels), Cancelled→Active (user resubscribes). Invalid: Trial→Cancelled (you can't cancel a trial), Expired→Active (must resubscribe via payment, not direct).

Test cases come straight from the diagram — TC1: Trial → pay → Active; TC2: Active → cancel → Cancelled; TC3: Trial → cancel → expect rejection (invalid); and so on.

The senior signal: also testing transition data integrity — does cancelling preserve user data, does resubscribing restore it, does expiry freeze it without deleting?

// EXAMPLE

subscription-states.md

States: Trial, Active, Cancelled, Expired

Valid transitions:
  Trial    -- pay()        --> Active
  Trial    -- trialEnd()   --> Expired
  Active   -- cancel()     --> Cancelled
  Cancelled -- resub()     --> Active
  Cancelled -- periodEnd() --> Expired

Invalid (must reject):
  Trial    -- cancel()     --> X   (no cancellable trial)
  Expired  -- resub()      --> X   (must repay, not direct)
  Active   -- pay()        --> X   (already active)

Test cases:
  TC1  Trial → pay        → Active
  TC2  Trial → trialEnd   → Expired
  TC3  Active → cancel    → Cancelled (verify data retained)
  TC4  Cancelled → resub  → Active (verify data restored)
  TC5  Cancelled → period → Expired
  TC6  Trial → cancel     → expect 4xx + state unchanged
  TC7  Expired → resub    → expect redirect to payment

// WHAT INTERVIEWERS LOOK FOR

Drawing or sketching a state diagram, awareness that invalid transitions need explicit tests, and mentioning transition data integrity.

// COMMON PITFALL

Only testing happy-path transitions and missing invalid ones — interviewers want explicit 'this transition shouldn't happen' tests.