- 이번엔 truffle을 사용하여 단위 테스트를 해볼 것이다.
자바스크립트 또는 솔리디티로 테스트 스크립트를 작성하여 단위 테스트를 수행할 것이다.
자바스크립트 테스트 프레임워크 mocah를 기반으로 contract 함수를 사용할 것이다.
단위 테스트 묶음 contract()에서는 각 단위 테스트 케이스의 결과를 공유하므로 순서를 고려해야 한다.
대부분의 메소드들은 비동기적으로 동작하므로 결과도 비동기적으로 작성해야 한다(Promise, aysnc/await).
- 아래코드를 test 디렉토리에 test_hello.js 파일을 만들어 작성하자.
var hello = artifacts.require("HelloWorld");
contract("HelloWorld", function() {
// say 메소드 테스트
it("should be same as constructor argument", async() => {
let instance = await hello.deployed();
let greeting = await instance.say.call();
assert.equal(greeting, "Hello, World!");
});
// setGreeting 메소드 테스트
it("should change the greeting value by setGreeting", async() => {
let instance = await hello.deployed();
await instance.setGreeting("Hello, Blockchain!", {from: web3.eth.accounts[0]});
let greeting = await instance.say.call();
assert.equal(greeting, "Hello, Blockchain!");
});
// 아래 방법과 동일하지만 async를 통해 더 직관적으로 작성 가능
/*
// say 메소드 테스트
it("should be same as constructor argument", function() {
// hello가 배포되고나면 리턴값을 instance 변수로 전달, instance가 contract를 나타내게 됨
return hello.deployed().then(function(instance) {
// say가 실행되고 나면 리턴값을 greeting 변수로 전달
return instance.say().then(function(greeting) {
assert.equal(greeting, "Hello, World!");
})
})
});
// setGreeting 메소드 테스트
it("should change the greeting value by setGreeting", function() {
return hello.deployed().then(function(instance) {
// 상태변수를 업데이트, 비용을 계정할 계정을 accounts[0]으로 설정
instance.setGreeting("Hello, Blockchain!", {from: web3.eth.accounts[0]});
return instance.say().then(function(greeting) {
assert.equal(greeting, "Hello, Blockchain!");
})
})
});
*/
});
- 파워쉘에서 테스트를 실행해보았더니 하나는 성공 하나는 실패했다. 이것도 버전 이슈인 것 같다...
열심히 구글링을 하여 해결방법을 찾아 다시 코드를 작성하였다.
var hello = artifacts.require("HelloWorld");
contract("HelloWorld", function() {
// say 메소드 테스트
it("should be same as constructor argument", async() => {
let instance = await hello.deployed();
let greeting = await instance.say.call();
assert.equal(greeting, "Hello, World!");
});
// setGreeting 메소드 테스트
it("should change the greeting value by setGreeting", async() => {
let instance = await hello.deployed();
let accounts = await web3.eth.getAccounts();
web3.eth.defaultAccount = accounts[0];
await instance.setGreeting("Hello, Blockchain!", {from: web3.eth.defaultAccount});
let greeting = await instance.say.call();
assert.equal(greeting, "Hello, Blockchain!");
});
// 아래 방법과 동일하지만 async를 통해 더 직관적으로 작성 가능
/*
// say 메소드 테스트
it("should be same as constructor argument", function() {
// hello가 배포되고나면 리턴값을 instance 변수로 전달, instance가 contract를 나타내게 됨
return hello.deployed().then(function(instance) {
// say가 실행되고 나면 리턴값을 greeting 변수로 전달
return instance.say().then(function(greeting) {
assert.equal(greeting, "Hello, World!");
})
})
});
// setGreeting 메소드 테스트
it("should change the greeting value by setGreeting", function() {
return hello.deployed().then(function(instance) {
// 상태변수를 업데이트, 비용을 계정할 계정을 accounts[0]으로 설정
instance.setGreeting("Hello, Blockchain!", {from: web3.eth.accounts[0]});
return instance.say().then(function(greeting) {
assert.equal(greeting, "Hello, Blockchain!");
})
})
});
*/
});
- 두 가지 테스트 모두 성공하였다! 만약 테스트 파일이 여러개일 경우 truffle test를 하면 모든 유닛 테스트를 한 번에
수행할 수 있다.
- 아래는 지금까지의 프로세스를 그림으로 표현한 것이니 참고하길 바란다.
- 추가로 자바스크립트 비동기 처리시(Promise, async/await) 유의 사항에 대해 살펴볼 것이다.
우선 가나슈의 Setting/Server 에 들어간다.
- 위 그림처럼 AUTOMINE이 켜져있으면 블럭이 즉시(instantaneously) 생성된다. 하지만 현실적으로 이더리움 블록이
생성 되는 데에는 몇 초정도 시간이 걸린다.
- AUTOMINE을 끄면 MINING BLOCK TIME을 설정 할 수 있는데 실제와 비슷하게 5초정도로 설정을 한다고 가정해보자.
만약 테스트 케이스가 비동기적인 결과를 반환 할 경우 promise를 사용하지 않으면 테스트 케이스에 실패 할 수 있으
므로 유의하자.
'Block Chain Development' 카테고리의 다른 글
이더리움 기반 Dapp 개발 연습 #6 (로직) (0) | 2022.02.05 |
---|---|
이더리움 기반 Dapp 개발 연습 #5 (Truffle React Unboxing) (0) | 2022.01.31 |
이더리움 기반 Dapp 개발 연습 #3 (배포) (0) | 2022.01.25 |
이더리움 기반 Dapp 개발 연습 #2 (컴파일) (0) | 2022.01.23 |
이더리움 기반 Dapp 개발 연습 #1 (개발환경 셋팅) (0) | 2022.01.21 |