Truffle : 스마트 컨트랙트 테스트 케이스 구현 방법

Seungwon Go
ReturnValues
Published in
6 min readSep 18, 2018

--

Truffle Framework를 이용해서 스마트 컨트랙트를 개발하는 이유 중 가장 큰 장점은 테스트 케이스를 작성해서 빠르고 손쉽게 테스트를 진행해 볼 수 있다는 것입니다. 이번 포스팅에서는 테스트 케이스를 구현하는 방법에 대해서 자세히 다루어 보려고 합니다.

스마트컨트랙트를 개발해서 메인넷 혹은 테스트넷에 배포해 보신 분들은 아시겠지만, 테스트를 진행하려면 굉장히 많은 시간을 소모해야 합니다. 각 케이스별로 DApp이 구현이 되여 있어야 하고, 매번 트랜잭션을 일으킬때마다 메타마스크를 통해 가스비를 지불해야 하는 등 여건 번거로운 것이 아닙니다.

그래서 오늘은 스마트컨트랙트를 로컬에서 효율적으로 테스팅 할 수 있는 방법을 소개하고자 합니다. 소개되는 예제는 지나번 포스팅한 Truffle Framework 기반 ERC20 토큰 개발/테스트/배포에서 작성되었던 예제인 ERC20 토큰을 기반으로 하기 때문에, 못 보신 분들은 꼭 보셔야 이해하실 수 있을것입니다.

Truffle에서는 Mocha(https://mochajs.org/) 테스팅 프레임워크를 이용해서 테스트 케이스를 구현하게 됩니다.

테스트케이스를 구현하는 방법을 알아보기전에 우리는 먼저 테스트케이스를 한글로 작성해 보도록 하겠습니다. 저는 SampleToken.sol에 대한 테스트케이스를 아래와 같이 작성해 보았습니다.

[테스트케이스 1 : 스마트컨트랙트가 선언된 변수에 맞게 정확히 생성되었는지 점검]
1.1. 토큰 이름은 지정한 이름으로 생성되었는가?
1.2. 토큰 심볼은 지정한 심볼로 생성되었는가?
1.3. 토큰 decimals은 지정한 decimals로 생성되었는가?
1.4. 토큰 총발행양은 지정한 total supply에 맞게 생성되었는가?
[테스트케이스 2 : 토큰 총발행양이 owner에게 제대로 transfer 되었는지 점검]
2.1. 발행된 전체 토큰양과 owner가 가지고 있는 토큰 balance가 동일한가?
[테스트케이스 3: 구현된 기능이 제대로 동작하는지 점검]
3.1. transfer 기능 점검 : 특정 address로 토큰 전송(transfer) 실행 후, 해당 address가 가지고 있는 토큰 balance가 전송된 토큰양과 일치 하는가?
3.2. 토큰 총발행양보다 더 많은 토큰을 전송하려고 할때, revert가 되는가?

위에 작성된 테스트 시나리오에 맞춰 테스팅 프로그램을 구현해 보기 앞서 Mocha 테스팅 프레임워크의 가장 기본적인 형태에 대한 학습을 먼저 진행 보도록 하겠습니다. 아마 앞으로 여러분이 작성할 테스트케이스 대부분이 이 형태로 모두 커버가 될거라 생각합니다.

Mocha의 기본구조

작성된 테스트 케이스 내의 함수의 기능을 살펴보도록 하겠습니다.

  • before : 함수 이름에서 알수 있듯이 테스팅 함수가 진행되기 전에 한번 호출 되는 함수 입니다.
  • beforeEach : 실제 테스트 케이스는 it() 함수 내에 작성을 하여 테스트 하게 되는데, beforeEach는 프로그램 내에 작성된 모든 it() 함수 실행전에 실행되는 함수 입니다.
  • afterEach : 프로그램 내에 작성된 모든 it() 함수 실행후에 실행되는 함수 입니다.
  • describe : 테스트 시나리오가 여러가지 있을 수 가 있는데, 저는 describe를 테스트 시나리오를 정의하여 시나리오별로 테스트 케이스를 분리하여 작성할 때 사용합니다.
  • it : 실제 각각의 테스트 케이스를 구현하는 함수입니다.
  • after : 함수 이름에서 알수 있듯이 테스팅 함수 전부가 실행되고 난 후에 한번 호출 되는 함수 입니다.

위의 테스트 케이스를 실행시키면 아래와 같이 출력이 됩니다.

콘솔에 출력된 순서를 보시면 실제 각 함수가 어떻게 동작하는지 정확히 이해가 되실겁니다.

그럼 앞서 작성한 SampleToken.sol 테스트 케이스에 대한 테스팅 프로그램 구조를 한번 잡아보도록 하겠습니다.

실행시키면 아래와 같이 콘솔에 출력이 됩니다.

이제 실제 각각의 테스트 케이스별 점검 프로그램을 it() 함수를 작성하면 됩니다. 전체 코드는 아래와 같습니다.

const SampleToken = artifacts.require("SampleToken");

artifacts.require는 node의 require에 비슷한 메소드라고 생각하시면 됩니다. 선언된 컨트랙트명이 SampleToken인 스마트컨트랙트를 반환해 줍니다.

우리는 beforeEach 함수내에서 SampleToken 컨트랙트를 생성해서, 각 테스트케이스인 it() 함수를 실행할때 항상 초기 상태의 SampleToken 컨트랙트로 테스트를 진행할 수 있도록 아래와 같이 작성하였습니다.

beforeEach(async function() {
token = await SampleToken.new(_name, _symbol, _decimals, _total_supply, {from: owner});
});

각 테스트 케이스별로 사용된 메소드는 Mocha 프레임워크의 Documentation을 참조하시면 좋을것 같습니다.

자 그럼 작성된 테스트 케이스를 실행해 봅시다.

우리가 작성한 테스트 시나리오 맞추어 테스팅 결과를 한눈에 알아보기 쉽도록 출력이 되었습니다.

스마트컨트랙트는 그 용도 자체가 굉장히 중요하고, 개발된 코드 역시 누구나 볼수 있어서 보안상 굉장히 취약합니다. 그렇게 때문에 더더욱더 실제 배포 전에 다양한 테스트 케이스를 작성해서 테스트를 반드시 수행해야 합니다.

작성된 프로그램 코드는 아래 Github에서 다운로드 받으실 수 있습니다.

https://github.com/returnvalues/truffle-tutorial-token/blob/master/test/SampleToken.test.js

--

--

Seungwon Go
ReturnValues

Writer, Youtuber, Investor, Programmer, Founder