Decision/Branch is a heuristic to identify new test cases based on the evaluation of branches. The existing test suite is analyzed for coverage. Any logical branch which could resolve in branching of control flow or errors is evaluated for all possible outcomes. If an outcome is not covered in the test suite, a new test case can be developed which tests the branch. Branch coverage is a stricter form of statement coverage.
### Worked example
Consider the OpenZeppelin `deploy` function below in the `Create2` library:
-- CODE language-solidity --
/**
* @dev Deploys a contract using `CREATE2`. The address where the contract
* will be deployed can be known in advance via {computeAddress}.
*
* The bytecode for a contract can be obtained from Solidity with
* `type(contractName).creationCode`.
*
* Requirements:
*
* - `bytecode` must not be empty.
* - `salt` must have not been used for `bytecode` already.
* - the factory must have a balance of at least `amount`.
* - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
*/
function deploy(
uint256 amount,
bytes32 salt,
bytes memory bytecode
) internal returns (address) {
address addr;
require(address(this).balance >= amount, "Create2: insufficient balance");
require(bytecode.length != 0, "Create2: bytecode length is zero");
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
require(addr != address(0), "Create2: Failed on deploy");
return addr;
}
This code has 3 branches/decision points:
- `address(this).balance` >= `amount` or the opposite
- `bytecode.length != 0` or the opposite
- `addr != address(0)` or the opposite
### Tools
- The `brownie` framework provides branch coverage information: [https://medium.com/coinmonks/brownie-evaluating-solidity-code-coverage-via-opcode-tracing-a7cf5a92d28c](https://medium.com/coinmonks/brownie-evaluating-solidity-code-coverage-via-opcode-tracing-a7cf5a92d28c)