1. Getting Set Up (~2)

  1. touch test/CryptoZombies.js로 빈 테스트 파일 생성
  2. Smart contract의 compile & migrate 과정은 다음과 같다
  • Compile: Solidity compiler가 JSON file을 생성한다. 이는 build artifacts라고도 불리며, contract의 이진 표현법이다.
    • const MyAwesomeContract = artifacts.require("MyAwesomeContract")에서 artifacts가 build artifacts를 의미한다.
  • Migrate: Truffle이 JSON file의 update 정보를 network에 올린다
  • Test: group test의 경우 contract()를 호출하며 이뤄진다. contract()는 다음 두개의 인자를 가진다
    • string: test 대상
    • callback: test를 작성할 위치

3. The first test - Creating a new zombie (~5)

Test는 deploy 전에, locally 수행해야 한다

Test Sequence

  1. Set up
  • contract abstraction은 말 그대로 abstraction이기 때문에 smart conract가 상호작용하기 위해서는 JS 객체를 만들어야 한다.
    • const contractInstance = await MyAwesomeContract.new();와 같이 선언할 수 있다.
  • test에 사용하는 인자들은 Alice's Awesome Zombie와 같은 구체적인 이름보다는 Zombie #1, Zombie #2와 같은 간결한 이름을 global하게 선언하여 사용하는 것이 좋다.
  • contractInstance.createRandomZombie(zombieName[0]);과 같이 contractInstance의 함수에게 인자를 전달해 함수를 실행할 수 있다.
  1. Act
  • 위의 Set up을 그대로 따라갔을 때, alice가 아닌 사람이 contract를 call했을 수 있다. 이런 보안 문제도 contract abstraction으로 해결할 수 있다.
    • const result = await contractInstance.createRandomZombie(zombieNames[0],{from:alice});
    • 위와 같이, {from:alice}를 넣어서 caller를 특정할 수 있다
  • 이렇게 선언한 result에는 로그 개념으로 접근할 수 있기 때문에, 다음과 같은 정보를 얻을 수 있다
    • result.tx: tx hash
    • result.receipt: result의 receipt 상태가 true인지 아닌지 확인 가능
  1. Assert
  • equal(), deepEqual(): function을 실행하고, 그 결과에 따라 error throw를 하기도 함

6. Keeping the Fun in the Game (~7)

  • assert()사용

8. Zombie Transfers

Transfer Scenarios

  • ERC721에 따라 다음 2개의 transfer scenario가 예상된다.
    1. Alice가 자신의 zombie를 직접 transfer 하는 경우: transferFrom을 직접 실행
    2. Alice가 자신의 zombie에 대한 Bob의 접근을 허용하고, Alice 혹은 Bob이 transfer 하는 경우: approve를 실행한 뒤 transferFrom을 실행

Context Function

  •   context("with the single-step transfer scenario", async () => {
        it("should transfer a zombie", async () => {
          // TODO: Test the single-step transfer scenario.
        })
    })
      context("with the two-step transfer scenario", async () => {
        it("should approve and then transfer a zombie when the approved address calls transferFrom",   async () => {
         // TODO: Test the two-step scenario. The approved address calls transferFrom
        })
        it("should approve and then transfer a zombie when the owner calls transferFrom", async () => {
      // TODO: Test the two-step scenario. The owner calls transferFrom
      })
      })
    
  • 위와 같이, multiple scenario에 대해 context 함수를 이용해 test 결과를 분리할 수 있다
  • 만약 multiple scenario에서 한 context내의 test 결과가 정상적으로 작동할 때 필연적으로 상충하는 경우, 순차적인 테스트를 위해 함수 앞에 문자 x를 붙일 수 있다. x가 붙어있는 context에 대해, truffle과 같은 compiler는 테스트를 진행하지 않는다