Process
Cause-Effect Graph Testing
Last updated:
December 13, 2021
We recommend familiarizing with [Decision Table Testing](/codex/decision-table-testing) before reading this article. While Decision Table testing focuses on multiple input conditions producing one output, Cause-Effect Graph Testing looks at how a set of system conditions (causes) affect a set of system outcomes (effects). Each cause and effect should be a boolean variable and there should be a clear boolean relationship between them – each effect should be defined as a boolean function over the causes. The resulting diagram is called the Cause-Efect Graph and each combination of inputs indicates a possible test case. Cause-Effect Graph Testing can be used to test functions with several side effects such as multiple state changes and/or event emissions during one function. ### Worked example Let's look at the OpenZeppelin ERC20 `transferFrom` implementation.

-- CODE language-solidity -- /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; }

The causes (input conditions) for `transferFrom` are the following: - A: Valid sender: `sender != 0x0` - B: Valid recipient: `recipient != 0x0` - C: Sufficient sender funds: `balanceOf(sender)` >= `amount` - D: Sufficient sender allowance: `allowances(sender, recipient)` >= `amount` To complete the Cause-Effect Graph, we need to define the possible effects and express them in terms of the causes. The possible effects are the following: - Return (A & B & C & D) - Update balances (A & B & C & D) - Emit `Transfer` event (A & B & C & D) - Revert: - Revert invalid sender if !A - Revert invalid recipient if A & !B - Revert insufficient allowance if A & B & !D - Revert insufficient funds if A & B & D & !C.
See Also: