rectangles-mixedState Based Testing

Quick Summary

  • Use the STAR-A mnemonic to help you remember what to test:

    • State - Every state can be reached

    • Transitions - All transitions work correctly

    • Actions - Actions in each state are valid and correct

    • Repeat - Repeat states/actions to find sequence-dependent bugs

    • Advanced

      • Interrupt transitions (abort, cancel, restart, make it fail, let it time out)

      • Revisit states and repeat transitions multiple times to find sequence-dependent bugs

      • Vary event triggers: user, external, internal, passage of time

  • Consider a combination of 1-switch or 2-switch coverage + Risk-based, Travelling Salesman or Chinese Postman paths.

Use cases for State Models

Creating a state model is common because state is everywhere - in both software and real life. Actions often depend on the current state, and these must be tested.

"High-level" or business examples:

  • Shopping cart: Empty → Items added → Checked out → Order placed

  • Ticket lifecycle: Open → In progress → Resolved → Closed → Reopened

  • ATM: Insert Card → Enter Pin → Withdraw Cash

"Low-level" or technical examples:

  • Service / API Lifecycle: Idle → Processing → Response Sent

  • Authentication: Logged out → Logged In → Session Expired

  • File Upload: Idle → Selecting File → Uploading → Verifying → Success / Error

Sample Models

Basic Template

spinner
  • A state leads to another state

  • A transition may lead back to the same state (self-loop, e.g., invalid input leads back to the same input prompt)

  • Composite States are high-level states that group related, low-level states

  • A choice (diamond) may lead to two or more paths and states

  • A fork may split or join paths

Elementary examples

spinner
spinner

You might notice that the above diagram doesn't explicitly cover:

  • The card may be ejected if it's invalid

  • The card may be swallowed after three consecutive incorrect PINs

  • All the possible transactions (withdraw, deposit, view balance, other) - instead, all transactions are bundled into a single transition

  • Test data (rarely represented in State Diagrams. Instead, complementary models and techniques are developed):

    • PIN: correct/incorrect values

    • Card types: supported/not supported

    • Withdrawal: defective input, sufficient/insufficient balance

    • etc.

circle-exclamation

Resources to learn State Diagrams more deeply:

Creating the Model

To create a state model:

  1. Compile the system's unique states [state] and all the transitions --> between them

  2. Decide on the level of abstraction (more or less detail) and understand the trade-offs

  3. Identify events causing the transition

  4. Define what happens during each transition

Ways to cover the graph

It's very challenging and often impractical to cover all combinations of all transitions (including transition pairs, triples, etc.). Consider the following ways to cover the entire State Diagram:

  • Happy Path: most used routes (don't guess, gather reliable information)

  • Risk-based Path: less common, but of critical importance

  • Travelling Salesman's route: all states in one test case at least once

  • Chinese Postman Route: all transitions (back and forth, if possible) at least one

  • Round-Trip: cover at least one complete cycle returning to the same state

The above variants prioritize maximum coverage in the shortest possible time (or with fewer actions taken). But this isn't necessarily robust testing.

Upgrading to N-Switch Coverage

spinner

In state-based testing:

  • 0-switch coverage → each test covers a single transition (no chaining of transitions)

  • 1-switch coverage → each test covers pairs of consecutive transitions (2 transitions, 3 states)

  • 2-switch coverage → each test covers a triple of consecutive transitions (3 transitions, 4 states)

  • N-switch coverage → each test covers sequences of N+1 consecutive transitions. Greater N leads to more robust testing, but it means exponentially more test cases.

circle-info

N refers to the number of consecutive transitions in a sequence you want to test

Given the State Diagram below, we can produce a 0-switch coverage table:

Start State
Event / Transition
End State

S1

{some action}

S2

S2

{some action}

S3

S3

{some action}

S4

S4

{some action}

S3

And the 1-switch coverage table (aka transition pairs: 2 transitions, 3 states):

Start State
Transition
Mid State
Transition
End State

S1

{some action}

S2

{some action}

S3

S2

{some action}

S3

{some action}

S4

S3

{some action}

S4

{some action}

S3

S4

{some action}

S3

{some action}

S4

Choosing Coverage Level

A: Both 0-switch and 1-switch (and any N-switch) allow covering all transitions and states. So how does greater N leads to more robust testing?

B: Greater transition sequences help catch bugs that only appear when certain transitions happen in sequence - e.g., state-dependent side effects or incorrect state updates after a chain of actions. (See "Advanced State Testing" below).

A: So let's choose greater N and go with 2-switch or even 3-switch testing.

B: 2-switch or greater become exponentially more complex (similar to adding conditions to a Decision Table). 1-switch is sometimes considered a practical baseline that can be complemented with:

Advanced State Testing

1. Interrupting Transitions

Creating/deleting, processing, verifying, uploading, downloading, importing/exporting - verbs in continuous tense are generally represented as transitions, not states. And they can be:

  • aborted (and restarted)

  • interrupted (and resumed)

  • timed out (and restarted)

  • failed (and retried)

Drawing

All of these can be triggered and tested. Additionally, such actions uncover further basis for testing:

  • Partial state persistence (if applicable): stop the system mid-transition, then restart:

    • Does the system remember partial progress?

    • Is the data corrupted after the progress finishes?

    • Are there undesired junk/leftover files from the first attempt?

  • Re-entrant actions: trigger the same action while it's in progress.

  • Error state recovery: entering a fault or error state, then confirm valid exit paths exist and function correctly.

2. Finding sequence-dependent bugs

Advanced testing involves revisiting states and repeating actions multiple times in the same or different sequences - some defects become apparent only after repeating certain steps (and sometimes in a specific sequence). This may be caused by:

  • Cache state - Old or stale data is retained between operations, leading to incorrect results when actions are repeated without clearing or refreshing the cache.

  • Resource leaks - Memory, file handles, or connections aren’t properly released, so repeating actions depletes resources and causes failures over time.

  • Cumulative state corruption - Small, unnoticed data inconsistencies build up with each repetition until they cause incorrect behavior or crashes.

3. Varying event triggers

User actions are not the only thing that can trigger an event. Consider the following to vary your testing efforts:

  • Externally generated events: those that come from outside the System Under Test (SUT). Typically, other systems or modules that your SUT integrates with.

  • System-generated events: those triggered by the SUT itself. Often, these events are the result of the system completing some background activity.

  • Passage of time: scheduled job, timeout, start of day, or other regular interval

Drawing

Free Browser Tools for UML Diagrams

  1. Mermaid Diagrams and Charts: http://mermaid.js.org/arrow-up-right

Further Resources

Last updated