티스토리 뷰

Solidity/Foundry

Foundry 테스트 작성하기

piatoss 2023. 10. 28. 16:32

 Foundry는 Solidity를 사용해 테스트를 작성합니다. 이 점에서 Javascript를 사용해야 하는 Truffle, Hardhat같은 툴체인과 차별점이 있습니다. 일반적으로 테스트는 'test' 디렉터리에 저장되며, '.t.sol' 확장자를 가집니다. 테스트 함수가 revert되면 테스트는 실패하는 것이고, 그 반대에는 테스트가 성공한 것으로 간주됩니다.

 

테스트 예제

 Foundry 테스트는 Forge 표준 라이브러리의 'Test' 컨트랙트를 사용하여 작성할 수 있습니다. Test 컨트랙트는 기본적인 로깅과 어설션(assertion)을 제공합니다.

pragma solidity ^0.8.13;

import "forge-std/Test.sol";

contract ContractBTest is Test {
    uint256 testNumber;

    function setUp() public {
        testNumber = 42;
    }

    function test_NumberIs42() public {
        assertEq(testNumber, 42);
    }

    function testFail_Subtract43() public {
        testNumber -= 43;
    }
}

 코드의 중요한 부분을 나누어 설명하면 다음과 같습니다.

 

1. Test 컨트랙트 불러오기

import "forge-std/Test.sol";

 Test 컨트랙트는 Forge 표준 라이브러리에서 불러올 수 있습니다.

2. Test 컨트랙트 상속

contract ContractBTest is Test {
    ...
}

 Test 컨트랙트를 상속하여 테스트를 위해 정의된 함수들을 사용할 수 있습니다.

3. setUp 함수를 통해 테스트 환경 설정

function setUp() public {
    testNumber = 42;
}

 setUp 함수는 선택적으로 작성하는 함수이며, 각 테스트 케이스가 실행되기 전에 실행됩니다.

4. test로 시작하는 함수를 통해 테스트 작성

function test_NumberIs42() public {
    assertEq(testNumber, 42);
}

 test로 시작하는 함수는 실패해서는 안되는 긍정 케이스에 대한 테스트입니다.

5. testFail로 시작하는 함수를 통해 실패하는 테스트 작성

function testFail_Subtract43() public {
    testNumber -= 43;
}

  testFail로 시작하는 함수는 test로 시작하는 함수와 반대로, 성공해서는 안되는 부정 케이스에 대한 테스트입니다.

6. 테스트 함수를 작성하는 좋은 습관

 test_Revert[If | When]_Condition 패턴과 expectRevert cheatcode를 조합하여 테스트 함수를 작성하는 것이 더 직관적인  테스트를 작성하는 좋은 습관입니다. 예를 들어, testFail_Subtract43보다는 testNumber에서 43을 뺐을 때 예상되는 오류를 expectRevert로 명시해주고 함수명을 test_CannotSubtract43으로 변경하여 uint256 타입의 값 42에서 43을 뺄 수 없음을 나타내는 것이 더 이해하기 쉽고 좋은 테스트라고 할 수 있습니다.

function test_CannotSubtract43() public {
    vm.expectRevert(stdError.arithmeticError);
    testNumber -= 43;
}

7.  테스트 컨트랙트의 배포

 테스트는 로컬에서 간단한 배포 과정을 거칩니다. 이 때 모든 테스트는 '0xb4c79daB8f259C7Aee6E5b2Aa729821864227e84' 주소로 배포됩니다. 만약 테스트 안에서 컨트랙트를 배포한다면 배포자는 '0xb4c7...7e84'가 됩니다. 따라서 배포된 컨트랙트에 대한 권한이 '0xb4c7...7e84'에게 부여됩니다. 예를 들어, 컨트랙트 배포자만 호출할 수 있는 함수를 '0xb4c7...7e84'가 호출할 수 있게 되는 것입니다.

테스트 함수는 반드시 external 또는 public 접근자로 선언되어야 합니다. internal과 private 접근자는 Forge가 인식하지 못합니다.

설정 공유

 헬퍼 추상 컨트랙트를 생성하고 상속함으로써 설정값을 공유할 수 있습니다. (실제 값이 공유되지는 않음)

abstract contract HelperContract {
    uint256 testNumber;
}

contract MyContractTest is Test, HelperContract {
    function setUp() public {
        testNumber = 42;
    }

    function test_NumberIs42() public {
        assertEq(testNumber, 42);
    }
}

contract MyOtherContractTest is Test, HelperContract {
    function setUp() public {
        testNumber = 43;
    }

    function test_NumberIs43() public {
        assertEq(testNumber, 43);
    }
}

📖 참고자료

 

Foundry Book

A book on all things Foundry

book.getfoundry.sh

글에서 수정이 필요한 부분이나 설명이 부족한 부분이 있다면 댓글로 남겨주세요!
최근에 올라온 글
최근에 달린 댓글
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday
글 보관함