book
book copied to clipboard
add example of "one contract per method test structure" defined in best practices
This applies to "General Test Guidance" section 3.1, add something like the following:
Below is an example of this pattern for a factory contract called MyFactory that deploys a child contract called Child. A sample, unimplemented MyFactory contract is below. The actual content of all methods is left out for brevity, and only function signatures and empty function bodies are shown.
// file: src/MyFactory.sol
contract MyFactory {
constructor() {}
function deploy(address owner) external {}
function computeAddress(address owner) external {}
}
Next we have it's test contract. Aside from the MyFactoryTest setup contract, all contract names match methods in the MyFactory contract in the order they appear, and each test function in the test contracts asserts on a single thing that function should do.
// file: test/MyFactory.t.sol
contract MyFactoryTest is Test {
// Setup to deploy contracts, etc. goes in this contract.
}
contract Constructor is MyFactoryTest {
function test_SetsChildContractLogicAddress() public {}
function test_SetsOwnerAddress() public {}
}
contract Deploy is MyFactoryTest {
function deployChild() internal returns (address) {} // helper method
function test_RevertsIf_CalledByAccountThatIsNotOwner(address caller) public {}
function test_IncrementsChildDeployCountByOne() public {}
function test_DeploysChildAsMinimalProxy() public {}
function test_InitializesChildContract() public {}
function test_SetsChildOwnerAddress() public {}
function test_EmitsChildDeployedEvent() public {}
function test_ReturnsAddressOfTheNewChildContract() public {}
}
contract ComputeAddress is MyFactoryTest {
function test_ComputesExpectedAddress() public {}
}