일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Vue.js
- ethers v6
- chainlink 설명
- 티스토리챌린지
- 스마트 컨트렉트 함수이름 중복
- 스마트컨트렉트 함수이름 중복 호출
- Vue
- 오블완
- 컨트렉트 배포 자동화
- ethers websocket
- 스마트컨트렉트프록시
- 러스트기초
- nest.js설명
- 러스트 기초 학습
- ethers typescript
- 체인의정석
- 스마트컨트렉트테스트
- multicall
- 러스트 기초
- 컨트렉트 동일한 함수이름 호출
- rust 기초
- ambiguous function description
- ethers
- ethers type
- 프록시배포구조
- 스마트컨트렉트 예약어 함수이름 중복
- SBT표준
- git rebase
- 머신러닝기초
- vue기초
- Today
- Total
체인의정석
hardhat 테스트 코드에서 beforeEach 사용하기 VS fixtures 사용하기 본문
하드햇에서 첫번째로 작성하게 되는 테스트 코드는 해피케이스에 대한 시나리오 테스트이다.
이 테스트가 끝나게 되면 테스트 커버리지를 100% 까지 올리기 위해서 온갖 오류를 직접 발생시켜야 한다.
하지만 스마트컨트렉트에서 대부분의 함수들은 특정 조건에서만 실행이 가능하기 때문에 특정 시점에서 분기가 일어나서 오류가 테스트되는 경우 앞에 기본 세팅은 반복이 되어야 한다는 문제점이 있다.
여기에 따라 beforeEach를 사용하기로 하였다.
일단 기본 포맷은 아래와 같다.
https://hardhat.org/hardhat-runner/docs/guides/test-contracts#using-fixtures
import { Contract } from "ethers";
describe("Lock", function () {
let lock: Contract;
let unlockTime: number;
let lockedAmount = 1_000_000_000;
beforeEach(async function () {
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS;
const Lock = await ethers.getContractFactory("Lock");
lock = await Lock.deploy(unlockTime, { value: lockedAmount });
});
it("some test", async function () {
// use the deployed contract
});
});
보면 describe 안에 변수를 정의한 후 beforeEach에 컨트렉트 배포를 넣은 후 동일 레벨 상에서 it을 넣어주는 식으로 코드를 작성하였다.
이러한 경우 초기에 작성한 케이스는 이미 입증이 되었기 때문에 해당 테스트 코드를 그대로 beforeEach안에 두고 테스트 케이스를 작성하는 방법이 가능하다. 이미 검증된 상태부터 이어서 예외상황에 대한 테스트를 하는 것이다. 그리고 콘솔로그는 찍히기 때문에 로그 값으로 중간중간 디버깅을 하거나 값을 체크할 수도 있다.
하지만 복잡하고 중간중간 커스터마이징이 필요한 경우라면 아래와 같이도 사용이 가능하다.
describe("Lock", function () {
async function deployOneYearLockFixture() {
const lockedAmount = 1_000_000_000;
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
const Lock = await ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
return { lock, unlockTime, lockedAmount };
}
it("Should set the right unlockTime", async function () {
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
// assert that the value is correct
expect(await lock.unlockTime()).to.equal(unlockTime);
});
it("Should revert with the right error if called too soon", async function () {
const { lock } = await loadFixture(deployOneYearLockFixture);
await expect(lock.withdraw()).to.be.revertedWith("You can't withdraw yet");
});
});
여기서 사용된 것이 loadFixture 이다.
loadFixture를 사용하면 하드햇 네트워크가 fixture 라는 것을 받아서 원하는 상태로 만들어 준다. 처음 loadFixture가 사용될 때는 LoadFixture가 실행되지만 그 다음부터는 실행 이후의 시점으로 네트워크가 리셋된다.
이에 따라서 코드 자체도 깔끔해지고 테스트 코드의 부하도 줄어들게 된다.
근데 현재 구조에서는 워낙
load fixture의 경우 다만 함수를 여러개 만들어서 관리하게 되면 조금 더 정신 없을 수도 있다는 생각이 들었다.
결국 테스트 코드가 복잡해지면 두개를 모두 사용하여 적절히 해야 더 가독성이 좋은 테스트 코드가 나오는거 같다.
이 부분은 테스트 코드 작성이 마무리될 때 쯔음 업데이트 해보겠다.
'블록체인 > Ethers & web3' 카테고리의 다른 글
ERC20 만들고 test code까지 작성하기 (0) | 2022.08.11 |
---|---|
스마트컨트렉트 테스트 코드, hardhat & ethers & Typescript에서 상황별 Big number 다루기 (0) | 2022.07.26 |
ethers에서 bigNumber를 number 형태로 고치기 + 테스트 값 비교 (0) | 2022.07.04 |
hardhat의 chainID를 수정하여 메타마스크와 연결하기, 메타마스크와 hardhat 테스트 네트워크 연결하는 법 (0) | 2022.06.30 |
주소가 CA인지 체크하는 방법 (0) | 2022.06.24 |