mocha測試框架-truffle

https://mochajs.org/
學習網址:
https://www.jianshu.com/p/9c78548caffa
https://www.jb51.net/article/106463.htm
在truffle框架的簡單使用中,咱們瞭解到它的測試模塊是包裝了mocha測試框架的,在這裏咱們選擇cryptopunks的truffle例子來相應講解:javascript

https://github.com/larvalabs/cryptopunkshtml

 

爲何要使用mocha這個測試模塊:前端

當咱們在開發,咱們每每會有如下的問題:java

參考:https://blog.csdn.net/imwebteam/article/details/53310958node

需求和開發脫節

當一份需求來了, 開發人員每每不能百分百的理解需求的內容(拋棄產品本身變動需求的可能性。。),這每每會讓開發人員開發出的功能會有跟需求有所差異,這會帶來額外的工做量git

開發和測試脫節

什麼是開發和測試脫節,說的是,當開發人員按照本身的想法開發完了一個需求。而後測試人員也按照本身的想法去測試這個需求,而後因爲雙方的分歧,致使測試認爲開發有bug,開發認爲測試是sb.github

那麼如何解決上面的問題呢?web

答案就是 選擇一種軟件敏捷開發模式npm

敏捷開發模式

目前比較流行的開發模式有兩種: TDD 和 BDDjson

TDD (Test Driven Development 測試驅動開發)

  • 測試來驅動開發
  • 其重點偏向開發
  • 測試用例是在約束開發者,使開發者的目標明確,設計出知足需求的系統

BDD (Behaviour Driven Development 行爲驅動開發)

  • 基於TDD發展,保持測試先行的理念
  • 其重點偏向設計
  • 在測試代碼中用一種天然通用語言的方式把系統的行爲描述出來
  • 將系統的設計和測試用例結合起來,進而驅動開發工做

兩種方式各有其特色,咱們一般選擇的是BDD的方式

爲了方便咱們編寫測試用例,咱們須要使用一些前端測試用例工具——mocha

 

在這個例子中咱們可以看見在其的test文件夾中寫了一些測試文件,好比咱們以cryptopunksmarket-setinitia.jsl這個文件爲例,看cryptopunks測試代碼cryptopunksmarket-setinitial.js

(1)Truffle測試框架學習:

參考:http://www.blockchainbrother.com/article/2082

Truffle 使用 Mocha 測試框架 和 Chai 斷言來給你提供一個可靠的框架編寫JavaScript測試。這裏須要注意到的一個很大的不一樣是它使用了contract()測試套件替代了describe()測試套件,這個函數基本和 describe() 同樣,只不過它能夠啓用clean-room 功能.  其過程以下:

     1. 每次contract()函數運行以前,您的合約會被從新部署到正在運行的以太坊客戶端,所以測試是在一個乾淨的合約環境下進行的。
     2. 這個contract()函數提供一個由您的以太坊客戶端生成的,能夠在編寫測試合約使用的帳戶列表。
好比:
contract('CryptoPunksMarket-setInitial', function (accounts) {});
在這裏accounts就是會返回在區塊鏈環境上的全部用戶的帳戶來讓測試使用
 
若是您不須要一個清潔的測試環境,那麼您仍然可使用describe()函數來運行普通的Mocha測試。
 
Truffle 沒法檢測出在測試中須要與哪些合約進行交互,因此您須要明確地指出這些合約。您可使用一個由Truffle提供的方法 artifacts.require()來作這些事情,它可讓您爲一個特定的合約,請求一個可用的合約抽象。
好比:var CryptoPunksMarket = artifacts.require("./CryptoPunksMarket.sol");
在測試中使用artifacts.require()的方式和在遷移中使用的方式相同,您只須要指定合約名稱,好比:
var CryptoPunksMarket = artifacts.require("CryptoPunksMarket");
CryptoPunksMarket就是在contracts文件夾中的智能合約文件的名字
 
由於truffle中已經將斷言庫  Chai 也包裝了進去,因此當想使用斷言,如assert時,能夠直接使用,不用導入模塊
其餘的部分基本上就與mocha相同了,詳細內容繼續往下看

(2)後面想要使用測試框架mocha,可是又不想使用truffle,因此就來學習這個框架怎麼單獨使用了,下面就是學習的過程:
固然,首先要安裝:

使用npm全局安裝:
npm install --g mocha
或者僅僅只是安裝在某個模塊:

npm install --save mocha
而後你就可使用了

1.要測試上面的代碼是否對的,所以就要編寫測試腳本,測試腳本與所要測試的源碼腳本同名,可是後綴名爲 .test.js或 .spec.js, 如:xx.test.js 或 xx.spec.js

2.測試腳本能夠包含一個或多個describe塊,describe塊稱爲 "測試套件",表示一組相關的測試,它是一個函數,有兩個參數,第一個參數是測試套件的名稱,第二個參數是一個實際執行的函數。
每一個describe塊也能夠包含一個或多個it塊,it塊稱爲 「測試用例",表示一個單獨的測試,是測試的最小單位,它也是一個函數,第一個參數也是測試用例的名稱,第二個參數是一個實際執行的函數,it塊之間是同步運行的。

describe 和 it 大量嵌套後,就造成了一顆樹。樹的非葉子節點都是測試集合,葉子節點即 it ,就是測試用例。

注意,若是一個describe 裏面沒有 it (好比下面:), Mocha將不會執行這個 describe。

3.理解斷言庫

學習文檔:http://www.chaijs.com


斷言庫能夠理解爲比較函數,也就是斷言函數是否和預期一致,若是一致則表示測試經過,若是不一致表示測試失敗。mocha自己是不包括斷言庫的,因此必須引入第三方斷言庫的,目前比較受歡迎的斷言庫有 should.js, expect.js, chai.
should.js是BDD風格
expect.js是expect風格的斷言
//下面介紹的是chai


chai的expect(), assert() 和 should的斷言
Mocha默認使用的是BDD的風格。expect和should都是BDD的風格,兩者使用相同的鏈式語言來組織斷言的,但不一樣在於他們初始化斷言的方式,expect使用
構造函數來建立斷言對象實例,而should經過爲 Object.prototype新增方法來實現斷言(should不支持IE),expect直接指向 chai.expect,
should則是 chai.should();
上面的代碼中 expect 是斷言的意思,該做用是判斷源碼的實際執行結果與預期結果是否一致,若是不一致就拋出一個錯誤

三種的使用方法簡單以下所示:

var expect = require('chai').expect;

expect(2).to.be.equal(2);

 

var assert = require('chai').assert;

assert.equal((await contract.totalSupply()).toNumber(), 10);

 

var should = require('chai').should();

cookies.should.not.be.empty;

cookies.id.should.equal('10001','not equal to 10001');

所以在執行上面代碼以前,
咱們須要在項目中安裝 chai, 以下命令:
npm install --save-dev chai

1)var expect = require('chai').expect;
即引用 chai 斷言庫,使用的是 expect斷言風格。
expect 官網API(http://chaijs.com/api/bdd/).


2)mocha測試代碼如何運行?
上面的add.test.js 編寫完成後,咱們須要運行測試代碼了,進入add.test.js代碼的目錄後,執行以下命令可運行:
mocha add.test.js

mocha命令後面也能夠指定多個文件,以下命令:
mocha xx.test.js yy.test.js
使用通配符:
或者咱們能夠運行以下命令,執行多個測試腳本文件:
mocha spec/{add,reduce}.js //目錄spec下的add.js和reduce.js文件
mocha spec/*.js //全部文件
mocha默認運行test子目錄裏面的測試腳本,咱們通常狀況下,能夠把測試腳本放在test目錄下,而後進入test的上層目錄,直接執行mocha命令便可:
mocha
而後你就會發現test目錄下第一層的因此測試文件都被運行了。命令只會執行test第一層目錄下全部文件,並不能執行嵌套目錄下的文件。
爲了執行全部嵌套目錄下的文件,咱們能夠 mocha命令後面加一個參數 --recursive 參數
更多的細節信息能夠看:https://www.cnblogs.com/tugenhua0707/p/8419534.html,固然以後你要補充一下

 


3)測試用例的鉤子
Mocha在describe塊之中,提供了測試用例的四個鉤子,before(), after(), beforeEach()和afterEach(),他們會在指定的時間內執行。
before(): 將會在全部測試用例執行以前運行,好比在以前插入數據等等操做。
after(): 會在全部測試執行以後運行,用於清理測試環境,回滾到清空數據狀態。
beforeEach(): 將會在每一個測試用例執行以前執行,可用於測試測試須要準備相關數據的條件。
afterEach(): 將會在每一個測試用例以後執行,可用於準備測試用例所需的後置條件。

4)理解異步鉤子函數
例子1:
var expect = require('chai').expect;
describe('異步鉤子函數', function() {
  var foo = false;
  beforeEach(function(){
    setTimeout(function(){
      foo = true;
    }, 50)
  });
  it('異步鉤子函數成功', function() {
    expect(foo).to.be.equal(true);
  })
});

結果:
異步鉤子函數
       異步鉤子函數成功:

      AssertionError: expected false to equal true
      + expected - actual

      -false
      +true

如上能夠看到測試失敗,緣由是由於setTimeout 是異步的,在setTimeout執行完以前,it函數已經被執行了,因此foo當時數據仍是false,
所以false不等於true了。


這時候 done參數出來了,在回調函數存在時候,它會告訴mocha,你正在編寫一個異步測試,會等到異步測試完成的時候來調用done函數,或者超過2秒後超時,以下代碼就能夠成功了;
var expect = require('chai').expect;
describe('異步鉤子函數', function() {
  var foo = false;
  beforeEach(function(done){
    setTimeout(function(){
      foo = true;
      // complete the async beforeEach
      done();
    }, 50)
  });
  it('異步鉤子函數成功', function() {
    expect(foo).to.be.equal(true);
  });
});

(3)這篇文章不是要很詳細地告訴你們概念性的內容,只是讓有跟我同樣想法(即學習了truffle框架後,發現裏面的那個測試十分有意思,想以後作測試的時候也用這種測試方法),可是忽然不知道怎麼入手的人一個方向,知道那是個什麼測試框架,以及去哪裏學習,以及一些比較簡單的必須知道的概念和內容,知道這些其實你就能夠寫一個十分簡單的測試例子了,建議結合別人的測試代碼進行學習,如https://github.com/larvalabs/cryptopunks/tree/master/test

在下面進行測試:

1)一開始,當我想要直接複製truffle中寫好的測試文件,進行小部分更改直接進行使用時,發現出錯:

truffle中只須要這兩句話就能夠部署好合約,可是在沒框架的狀況下是不能夠的
var testToken = artifacts.require(「./test-punk.sol」);
instance = await testToken.deployed(50);

這樣會報錯:
1.ReferenceError: artifacts is not defined
2.(function (exports, require, module, __filename, __dirname) { pragma solidity ^0.4.20;
                                                                     ^^^^^^^^
SyntaxError: Unexpected identifier

因此這就說明了在框架外是不能夠這樣子進行合約的編譯的

經過上面咱們就可以知道truffle到使用上面兩句部署指令前,還進行了編譯compile和部署migrate,因此在測試前要將合約的編譯和部署都弄好,你能夠經過查看我寫的remix的使用來學怎麼使用remix進行編譯和部署或者是看nodejs部署智能合約的方法來本身編寫代碼進行編譯和部署,最終獲得合約的部署地址NFMAddress

部署成功後,以後若是想在別的地方進行使用,須要如下幾句話句話:

const NFMAbi = require("./testToken.json");//合約生成的Abi,通常爲json文件

const NFMContract = web3.eth.contract(NFMAbi);
const instance = NFMContract.at(NFMAddress);

此時就可以調用該函數中的函數及變量了

 

2)其次,還要記得將相應的模塊包下載下來,這裏要添加package.json文件配置等內容

Error: Cannot find module ‘web3'
你安裝的web3必定要放在本地的node_modules文件夾下,否則是讀不出來的

3)使用nodejs來進行合約的編譯和部署時,發現出現下面的錯誤
1.let abi = compiledContract.contracts['testToken'].interface;
出錯:
TypeError: Cannot read property 'interface' of undefined

而後輸出compiledContract進行查看
2.console.log(compiledContract);
發如今編譯處就出錯了
{ contracts: {},
  errors:
   [ ':49:17: ParserError: Expected identifier, got \'LParen\'\n    constructor (uint number) public{\n                ^\n' ],
  sourceList: [ '' ],
  sources: {} }
還有:
{ contracts: {},
  errors:
   [ ':26:9: TypeError: Wrong argument count for function call: 2 arguments given but expected 1.\n        require(propertyValueToOwner[propertyValue] == 0x0,\'this is not the first-sell\');\n        ^------------------------------------------------------------------------------^\n',
發現多是版本的問題,由於這裏聲明構造函數使用了新的聲明方式,可是在這裏沒能被識別出。因此下載了新版本的solc,而後就成功了

4)

contract('testToken',async (accounts) => {
出錯:ReferenceError: contract is not defined
由於contract是truffle框架弄的,不在框架中是不可以這樣使用的,這時候想要使用帳號只能老實地鏈接區塊鏈,經過web3模塊去調用API接口

var Web3 = require("web3");

web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8201"));

account1 = web3.eth.accounts[0];


5)最後運行結果也有問題:
用戶deMBP:testToken 用戶$ mocha test-mocha.js

  testToken Test
check tokenNumber
    1) deploy contract
    2) sell token
    3) buy token
    4) check the balance
    5) withdrawl the balance


  0 passing (118ms)
  5 failing

  1) testToken Test
       deploy contract:
     TypeError: Cannot read property 'call' of undefined
      at Context.<anonymous> (test-mocha.js:56:43)

  2) testToken Test
       sell token:
     TypeError: Cannot read property 'sellToken' of undefined
      at Context.<anonymous> (test-mocha.js:77:19)

  3) testToken Test
       buy token:
     TypeError: Cannot read property 'testTokenIdToOwner' of undefined
      at Context.<anonymous> (test-mocha.js:90:25)

  4) testToken Test
       check the balance:
     TypeError: Cannot read property 'pendingDrawalOfUser' of undefined
      at Context.<anonymous> (test-mocha.js:112:38)

  5) testToken Test
       withdrawl the balance:
     TypeError: Cannot read property 'pendingDrawalOfUser' of undefined
      at Context.<anonymous> (test-mocha.js:124:31)

Contract mined! address: 0x3cb4464f73eda60ac3ba1d46cd0544cd7ae18040 transactionHash: 0x62f27e3ccdfcb6ba54547107bbc8f1f9f152f0f588eddec9b1dc3a65d1d7d047

後面發現這個緣由是部署回調獲得instance前,it函數中的內容就已經開始調用了,這樣的話怎麼着instance都是undefined的,那麼確定是不可能可以調用合約中的函數的。並且在這裏將部署函數放在了一個單獨的it測試用例當中,可是下面的測試用例都是應該等待部署完成後纔可以測試成功的,那麼這樣就不可能成功測試了,由於it測試用例是同步進行的,在部署的同時,其餘測試用例也都開始運行了,⚠️有先後關係的測試內容應該要寫在一個測試用例當中。


因此就不作在這以前進行部署的事情了,畢竟咱們確定在測試以前是已經把合約部署上去的了,那麼只要用
let instance = MyContract.at('0x86757c9bdea10815e7d75a1577b6d9d2825dae0a');
這句話就好了

6)而後再運行也出錯:
mocha Error: Timeout of 2000ms exceeded.
則須要你再運行的時候添加
mocha -t 20000 test.js
由於其默認的時間是2000ms,你的時間若是過大,能夠進行本身設置

7)當你使用describe這些mocha的形式語句的時候,使用node test.js是不能運行成功的,會返回錯誤:

用戶MBP:testToken 用戶$ node test.js
/Users/用戶/testToken/test.js:165
describe('testToken',function(){
^
ReferenceError: describe is not defined

因此必定要用mocha開頭,mocha test.js

實現:

const debug = require("debug")("testToken"); const assert = require('assert') // var testToken = require("./test-punk.sol");
const Web3 = require('web3'); const web3 = new Web3(); web3.setProvider(new Web3.providers.HttpProvider('http://127.0.0.1:7545')); const fs = require("fs"); const solc = require("solc"); let source = fs.readFileSync("testToken.sol",'utf8');//read file
let compiledContract = solc.compile(source,1);//compile // console.log(compiledContract);

for (let contractName in compiledContract.contracts) { console.log("in"); var bytecode = compiledContract.contracts[contractName].bytecode; var abi = JSON.parse(compiledContract.contracts[contractName].interface); //將abi寫成json形式
    console.log("out"); } // 你要測試的是接口 // console.log(bytecode); // console.log(abi);
 let gasEstimate = web3.eth.estimateGas({data:'0x'+bytecode}); let MyContract = web3.eth.contract(abi); debug("deploying contract"); // let instance;
let instance = MyContract.at('0x86757c9bdea10815e7d75a1577b6d9d2825dae0a');//可改


var user1 = web3.eth.accounts[0]; console.log(user1); var user2 = web3.eth.accounts[1]; var user3 = web3.eth.accounts[2]; var user4 = web3.eth.accounts[3]; var user5 = web3.eth.accounts[4]; var propertyValues = ['0x00000001','0x00000002','0x00000003','0x00000004','0x00000005']; var prices = [11,12,13,14,15]; var users = [user1,user2,user3,user4,user5]; //這個地方是想要在這裏同時部署合約,可是發現老是不成功,部署異步老是太慢,before()函數好像也沒有什麼用,因此後面我也只能放棄部署了,只能先部署完獲得地址再來調用了 // function deployContract() { // instance = MyContract.new(50,{from:user1,data:'0x'+bytecode,gas:47000000},function(e,contract){ // if(typeof contract.address !== 'undefined'){ // console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash); // } // }); // } // before(deployContract); // var instance;
describe("testToken Test",function(){ // it("deploy contract",async function(){
 it("contract begin",async function(){ let num = propertyValues.length; // instance = await testToken.deployed(50);
 console.log(instance.address); console.log('check tokenNumber'); console.log(await instance.tokenNumber.call()); debug("create token");
     //首先先建立5個token
for(let i=0; i<num; i++){ await instance.create(propertyValues[i],prices[i],{from:users[i],value:prices[i],gas:30000000}); } debug("display token");
     //而後查看生成的token的屬性 let nextTokenId
= await instance.nextTokenToCreate.call(); console.log("nextTokenId is :"+ nextTokenId); if(parseInt(nextTokenId) != 5){ console.log("initial token failed"); }else{ for(let i =0; i<num; i++){ console.log(await instance.propertyOfToken.call(i)); } } });   //而後sell token it("sell token",async function(){ await instance.sellToken(0,21,{from:user1,gas:30000000}); await instance.sellToken(1,22,{from:user2,gas:30000000});      //查看是否成功sell console.log(await instance.tokenIdToSell.call(0)); console.log(await instance.tokenIdToSell.call(1)); });    //其餘用戶對sell的token進行購買 it("buy token",async function(){
     //查看購買前token的擁有者是誰 console.log(instance.testTokenIdToOwner.call(
0)); console.log(instance.testTokenIdToOwner.call(1)); await instance.buyToken(0,{from:user3,value:21,gas:30000000}); await instance.buyToken(1,{from:user4,value:22,gas:30000000}); let buyer1 = await instance.testTokenIdToOwner.call(0); let buyer2 = await instance.testTokenIdToOwner.call(1);     //查看購買後的擁有者是誰來覈實購買成功進行 console.log(buyer1); console.log(buyer2); console.log("check the sell after buying"); console.log(await instance.tokenIdToSell.call(0)); console.log(await instance.tokenIdToSell.call(1)); assert.equal(buyer1,user3,"buying 0 is failed"); assert.equal(buyer2,user4,"buying 1 is failed"); });    //查看用戶臨時帳戶中此時有多少積蓄 it("check the balance",async function(){ let user1Balance = await instance.pendingDrawalOfUser.call(user1); let user2Balance = await instance.pendingDrawalOfUser.call(user2); console.log(user1Balance); console.log(user2Balance); assert.equal(user1Balance,21,"user1 balance number is not right"); assert.equal(user2Balance,22,"user1 balance number is not right"); });   //而後將臨時帳戶中的錢轉到錢包中 it("withdrawl the balance",async function(){ console.log(await instance.pendingDrawalOfUser.call(user1)); console.log(await instance.pendingDrawalOfUser.call(user2)); await instance.withdrawl({from:user1,gas:30000000}); await instance.withdrawl({from:user2,gas:30000000}); console.log(await instance.pendingDrawalOfUser.call(user1)); console.log(await instance.pendingDrawalOfUser.call(user2)); }); }); 結果是: 用戶deMBP:testToken 用戶$ mocha test-mocha.js in out 0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8 testToken Test 0x86757c9bdea10815e7d75a1577b6d9d2825dae0a check tokenNumber BigNumber { s: 1, e: 1, c: [ 50 ] } nextTokenId is :5
//生成的token的屬性 [ BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x0000000100000000000000000000000000000000000000000000000000000000', '0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8', BigNumber { s: 1, e: 1, c: [ 11 ] } ] [ BigNumber { s: 1, e: 0, c: [ 1 ] }, '0x0000000200000000000000000000000000000000000000000000000000000000', '0x7ddad6a67544efb0c51808c77009a7b98cc81630', BigNumber { s: 1, e: 1, c: [ 12 ] } ] [ BigNumber { s: 1, e: 0, c: [ 2 ] }, '0x0000000300000000000000000000000000000000000000000000000000000000', '0xe9478ebcf4c755ad945a351261c8fa046672963b', BigNumber { s: 1, e: 1, c: [ 13 ] } ] [ BigNumber { s: 1, e: 0, c: [ 3 ] }, '0x0000000400000000000000000000000000000000000000000000000000000000', '0x920f422b761976972a9eadbec1f5341a9747ea6a', BigNumber { s: 1, e: 1, c: [ 14 ] } ] [ BigNumber { s: 1, e: 0, c: [ 4 ] }, '0x0000000500000000000000000000000000000000000000000000000000000000', '0xa17a7fa74a7dd57dff005b45234292e7daaf150c', BigNumber { s: 1, e: 1, c: [ 15 ] } ] ✓ contract begin (1541ms)
// [
true, '0x0000000100000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8', BigNumber { s: 1, e: 1, c: [ 21 ] } ] [ true, '0x0000000200000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 1 ] }, '0x7ddad6a67544efb0c51808c77009a7b98cc81630', BigNumber { s: 1, e: 1, c: [ 22 ] } ] ✓ sell token (663ms) 0x3455f15cc11f2e77c055f931a6c918ccc7c18fd8 0x7ddad6a67544efb0c51808c77009a7b98cc81630 0xe9478ebcf4c755ad945a351261c8fa046672963b 0x920f422b761976972a9eadbec1f5341a9747ea6a check the sell after buying [ false, '0x0000000100000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] }, '0x0000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] } ] [ false, '0x0000000200000000000000000000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 1 ] }, '0x0000000000000000000000000000000000000000', BigNumber { s: 1, e: 0, c: [ 0 ] } ] ✓ buy token (954ms) BigNumber { s: 1, e: 1, c: [ 21 ] } BigNumber { s: 1, e: 1, c: [ 22 ] } ✓ check the balance (206ms) BigNumber { s: 1, e: 1, c: [ 21 ] } BigNumber { s: 1, e: 1, c: [ 22 ] } BigNumber { s: 1, e: 0, c: [ 0 ] } BigNumber { s: 1, e: 0, c: [ 0 ] } ✓ withdrawl the balance (631ms) 5 passing (4s)

 注意:在這裏看好像這個例子也可以順序執行,可是後面發現上面例子的因此it應該合成一個it來寫,否則順序是不必定能保證的,由於it測試用例在運行時是同步運行的,可是我這裏的測試用例實際上是有但願它按照順序來運行,因此改成:

describe("testToken Test",function(){ it("contract begin",async function(){ let num = propertyValues.length; // instance = await testToken.deployed(50);
 console.log(instance.address); console.log('check tokenNumber'); console.log(await instance.tokenNumber.call()); debug("create token");      //首先先建立5個token
        for(let i=0; i<num; i++){ await instance.create(propertyValues[i],prices[i],{from:users[i],value:prices[i],gas:30000000}); } debug("display token");      //而後查看生成的token的屬性
        let nextTokenId = await instance.nextTokenToCreate.call(); console.log("nextTokenId is :"+ nextTokenId); if(parseInt(nextTokenId) != 5){ console.log("initial token failed"); }else{ for(let i =0; i<num; i++){ console.log(await instance.propertyOfToken.call(i)); } } //而後sell token
        await instance.sellToken(0,21,{from:user1,gas:30000000}); await instance.sellToken(1,22,{from:user2,gas:30000000});      //查看是否成功sell
        console.log(await instance.tokenIdToSell.call(0)); console.log(await instance.tokenIdToSell.call(1)); //其餘用戶對sell的token進行購買
     //查看購買前token的擁有者是誰
        console.log(instance.testTokenIdToOwner.call(0)); console.log(instance.testTokenIdToOwner.call(1)); await instance.buyToken(0,{from:user3,value:21,gas:30000000}); await instance.buyToken(1,{from:user4,value:22,gas:30000000}); let buyer1 = await instance.testTokenIdToOwner.call(0); let buyer2 = await instance.testTokenIdToOwner.call(1);     //查看購買後的擁有者是誰來覈實購買成功進行
 console.log(buyer1); console.log(buyer2); console.log("check the sell after buying"); console.log(await instance.tokenIdToSell.call(0)); console.log(await instance.tokenIdToSell.call(1)); assert.equal(buyer1,user3,"buying 0 is failed"); assert.equal(buyer2,user4,"buying 1 is failed");    //查看用戶臨時帳戶中此時有多少積蓄
        let user1Balance = await instance.pendingDrawalOfUser.call(user1); let user2Balance = await instance.pendingDrawalOfUser.call(user2); console.log(user1Balance); console.log(user2Balance); assert.equal(user1Balance,21,"user1 balance number is not right"); assert.equal(user2Balance,22,"user1 balance number is not right");      //而後將臨時帳戶中的錢轉到錢包中
 console.log(await instance.pendingDrawalOfUser.call(user1)); console.log(await instance.pendingDrawalOfUser.call(user2)); await instance.withdrawl({from:user1,gas:30000000}); await instance.withdrawl({from:user2,gas:30000000}); console.log(await instance.pendingDrawalOfUser.call(user1)); console.log(await instance.pendingDrawalOfUser.call(user2)); }); });
相關文章
相關標籤/搜索