Process
Equivalence Partitioning
Last updated:
December 13, 2021
Equivalence Partitioning is a testing heuristic to determine which inputs should be tested for a given function. It relies on splitting the inputs into equivalence classes. Inputs from each class are expected to behave similarly so equivalence partitioning dictates that at least one representative member from each equivalence class should be tested. This technique can be generalized by looking at output partitions or other partitions of intermediate values in the code. ### Worked example Let's consider how we would test the `toString` function from OpenZeppelin contracts.

-- CODE language-solidity -- /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); }

We would expect this kind of routine to involve a loop based on the length of the string. The three equivalence classes could be constructed based on whether the loop is running for 0, 1 or more iterations. The equivalence classes would be as follows: - `0` (representative value `0`) - `1-9` (representative value `7`) - `10+` (representative value `9738053`). OpenZeppelin chose the following cases to test in this case: ```javascript describe('from uint256 - decimal format', function () { it('converts 0', async function () { expect(await this.strings.fromUint256(0)).to.equal('0'); }); it('converts a positive number', async function () { expect(await this.strings.fromUint256(4132)).to.equal('4132'); }); it('converts MAX_UINT256', async function () { expect(await this.strings.fromUint256(constants.MAX_UINT256)).to.equal(constants.MAX_UINT256.toString()); }); }); ``` The `MAX_UINT256` value is what we call a **boundary value** and discussed in [Boundary Value Analysis](/codex/boundary-value-analysis).
See Also: