Skip to content

Latest commit

 

History

History
65 lines (51 loc) · 2.61 KB

File metadata and controls

65 lines (51 loc) · 2.61 KB

State Transition Testing

See also: 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.

/**
 * @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 and 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.