Process
State Transition Testing
Last updated:
December 13, 2021
See also: [State Transition Review](/codex/state-transition-review). State Machine Testing models the system as a state machine with a set of states and transitions between them. State machine testing focuses on testing all possible transitions of a certain fixed length (for example all transition sequences of 1-2 transitions). ### Worked example Let's look at the OpenZeppelin Counters implementation.

-- CODE language-solidity -- /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }

We can immediately identify each state by the number `_value` and three possible transitions: - `increment` which moves us from state `n` to `n + 1` - `decrement` which moves us from state `n` to `n - 1` - `reset` which moves us from state `n` to `0` . Let's assume we want to test all 2-sequences of transitions. In that case we still have `MAX_UINT256` possible states to test which is too many. Instead, by using [Equivalence Partitioning](/codex/equivalence-partitioning) and [Boundary Value Analysis](/codex/boundary-value-analysis), we can identify two equivalence classes `{0}` and `1+` with 4 meaningful starting states to test: - `0` – boundary value - `1` – boundary value - `93588` – representative value of equivalence class - `MAX_UINT256` – boundary value. For each starting states we could test the 9 possible combinations of transitions.
See Also: