Process
Condition Testing
Last updated:
December 13, 2021
Condition Testing is a stronger version of [Decision/Branch Testing](/codex/decision-branch-testing). While branch coverage is focused on branches alone, condition testing is focused on all the boolean subexpressions of the branching conditions. ### Multiple condition testing Multiple condition testing is analogous to [Decision Table Testing](/codex/decision-table-testing) and relies on testing all possible combinations of condition sub-expressions. ### Condition determination testing A more efficient technique involves figuring out which conditions independently affect a decision outcome and only testing those. This technique analogous to collapsing of decision trees in [Decision Table Testing](/codex/decision-table-testing). ### Worked example Consider the OpenZeppelin `findUpperBound` function below in the `Arrays` library:

-- CODE language-solidity -- /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = Math.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { return low - 1; } else { return low; } }

If we focus on the last `if` statement, there are only two branches: - `low` > `0` && `array[low - 1] == element` - `low` <= `0 || array[low - 1] != element` (the inverse condition). However, there are four possible condition combinations: - `low` > `0` && `array[low - 1] == element` - `low` <= `0` && `array[low - 1] == element` - `low` > `0` && `array[low - 1] != element` - `low` <= `0` && `array[low - 1] != element` These are developed by considering the two subexpressions (`low` > `0` and `array[low - 1] == element`) and how they independently affect the branch condition outcome.
See Also: