book icon indicating copy to clipboard operation
book copied to clipboard

add example of "one contract per method test structure" defined in best practices

Open mds1 opened this issue 3 years ago • 0 comments

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 {}
}

mds1 avatar Feb 21 '23 20:02 mds1