使用Truffle作smart contract測試及debug - II 測試

版本 - truffle 4.1.11

延續上篇,繼續講測試的部分
寫test case有兩個方式,一個是用solidity另一個是用javascript,官方文件寫得還滿清楚的。記得你寫的test case的檔案,要放在test/

先介紹solidity的寫法,要先import下面這兩個smart contract,當然也要記得import你自己的smart contract
import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import "../contracts/Token777.sol";


 再來是命名規則,contract要以 Test 為開頭,測試function要以 test 為開頭
contract TestTaroToken { function testMint() public { Token777 token = Token777(DeployedAddresses.Token777()); address user = 0x2849f61e08B66A3b0eC2512613092174Df19Db1e; uint base = token.balanceOf(user);
uint incremental = 30000000000000000000; token.mint(user,incremental,""); Assert.equal(token.balanceOf(user), base+incremental, "balance is not equal"); } }

test case看起來相當直覺,就是先取得contract object後,呼叫mint(你想測試的function)這個function,最後用Assert確認結果,跟我們一般寫UT很相似。當然也有提供 beforeAll, beforeEach, afterAll 跟 afterEach這類的功能(就是在每個case前後,或是整個測試的一開始跟結束)。不過官方的介紹真的很少,例如怎麼使用預設的account或是我用不同的身份去執行等,我當然也還沒更深入去研究,不過 js 相較之下方便許多(雖然我不會 js...)。


再來介紹用js寫test case
var Token = artifacts.require("Token777"); var TokenReceiver = artifacts.require("TokenReceiver"); contract('Token', function(accounts) { it("check contract event", function() { var token; var transferAmount = 2000000000000000000; var receipt; return Token.deployed().then(function(instance) { token = instance; TokenReceiver.deployed().then(function(instance2) { receipt = instance2; return token.mint(accounts[0], incremental, ""); }).then(function(result) { return token.sendT(receipt.address, transferAmount, ""); }).then(function(result) { var flag = false; for (var i = 0; i < result.logs.length; i++) { var log = result.logs[i]; if (log.event == "EvGotToken") { flag = true; break; } } assert.equal(true, flag, "EvGotToken not found"); }); }); }); });

使用artifacts.require() import你要的contract。每一個case用 it 最為開頭,再來就是 js的語法。比較值得一提的是執行完某個contract 的function,這裡都拿得到transaction receipt,所以能做的判斷跟多得很多,而且是支援web3物件。

寫test case的細節,這裡沒有要提,看起來都還滿直覺的,主要想分享自己踩到雷的地方,一個是test 寫法是 Token.deployed()或是DeployedAddresses.Token777(),我一開始都以為是truffle內部會去抓已經部署好的contract,然後執行,不過後來發現,這個動作其實是去重新create contract,所以如果你測試的function需要一個前置狀態的話,例如要先有錢的話,那最好可以善用before這類的這類的方法。

test cases寫完後,再來就執行
$ truffle test

如果想執行某個測試檔案,在test後多加檔名就可以了
$ truffle test ./test/TestToken.js

執行結果就會像這樣
TestToken 1) testMint > No events were emitted 0 passing (2s) 1 failing 1) TestTaroToken testMint: Error: VM Exception while processing transaction: revert at Object.InvalidResponse (C:\Users\kimiw\AppData\Roaming\npm\no....

哪有第一次執行就會成功的,有8成應該都是會有狀況的,失敗的結果大概長這樣,最後面會寫原因,如果有收到部分event就會像這樣
Events emitted during test: --------------------------- EvGotToken(from: 0x65aff2ede7cca3d6eb54f2005a6e5e9ffc42bfb5, amount: 30000000000000000000, time: 1530699691) TestEvent(result: <indexed>, message: balance is not equal (Tested: 0, Against: 30000000000000000000)) ---------------------------

這個時候就可以去Ganache的Log去撈transaction hash,作接下來的debug!

留言

  1. Las Vegas Casino and Hotel - Jtm Hub
    › harrahs-gas-casino › harrahs-gas-casino With 여수 출장마사지 over 600,000 sq ft 안성 출장마사지 of 이천 출장안마 gaming machines, over 대전광역 출장안마 1,200 청주 출장샵 slot machines, the only place to watch and bet in Las Vegas.

    回覆刪除

張貼留言

這個網誌中的熱門文章

What's New in Ethereum Serenity (2.0)

瑞士滑雪分享2 - 策馬特

動手實做零知識 - circom