零、環境
1.依賴包
const { BN, constants, expectEvent, shouldFail } = require('openzeppelin-test-helpers');
2.全局變量
const { ZERO_ADDRESS,MAX_UINT256,MAX_INT256,MIN_INT256} = constants;
3.特殊的函數
// 每一個單元測試前(後)做的事情。
beforeEach(async function(){ ToDoSomeThing; });
afterEach(async function(){ ToDoSomeThing; });
// 總體的前面執行的函數,這個貌似沒什麼用
after(async function(){ ToDoSomeThing; });
before(async function(){ ToDoSomeThing; });
一、部署
1.加載合約對象
const ContractName = artifacts.require('ContractName');
2.部署新合約
this.contractName = await ContractName.new({from:accounts[0]});
3.讀取已部署合約
this.contractName = await ContractName.deployed();
二、合約交互
1.讀取合約地址
// 不能合併成一句話,否則讀取不到合約信息!!!
var contractObj = ContractName.deployed();
var contractAddr = contractObj.address;
2函數交互
// 構建交易,默認使用accounts[0]作爲簽名者
it("測試交易級函數", async function(){
var erc20 = ERC20.deployed();
await erc20.transfer(userAddr, amountBN, {
value: 0,
from: accounts[0]
});
(await erc20.balanceOf(userAddr)).should.be.bignumber.equal(amountBN,'Error String');
});
3.捕獲日誌
it('測試捕獲日誌', async function(){
var erc20 = ERC20.deployed();
const { logs } = await erc20.transfer(userAddr, amountBN, {from: accounts[0]});
expectEvent.inLogs(logs,'Transfer',{
from: accounts[0],
to: userAddr,
value: amountBN
});
});
4.異常處理
錯誤類型:
reverting : revert
throwing : invalid opcode
outOfGas : out of gas
shouldFail : 3種中的一種
示例:
it('測試異常', async function(){
var erc20 = ERC20.deployed();
await shouldFail.reverting(erc20.transfer(to,amount),{from:accounts[1]});
// 判斷拋出異常的信息。
await shouldFail.reverting.withMessage(erc20.function({ from: other }), "Unauthorized");
});
三、斷言
1.等於,不等於
it("test equal", async function(){
var actualValue = await erc20.balanceOf(accounts[0]);
var expected = new BN("100");
await actualValue.should.be.bignumber.equal(expected);
//await actualValue.should.not.be.bignumber.equal(expected);
});
2.比大小
actualValue.should.be.bignumber.above(expected); // 實際 大於 期望, gt,greaterThan
above(2); // 大於2
below(4); // 小於4
at.least(3); // 最小爲3
at.most(3); //
within(2,4);
3.other
should.exist();
四、數值處理
1.bignumber
// 新建,可以是數值,也可以是字符串,大值,只能用字符串。
var amount1 = new BN(100);
var amount2 = new BN("100000000000000000000000");
var amount3 = new BN('10').pow(new BN('22'));
// 運算,加普通數值要使用 addn,subn,muln,divn
amount1.add(amount2); // BN + BN 直接使用add
amount1.addn(100);
//斷言判斷時,需要加bignumber修飾,不然一定不相等。2個不同的BN實例
amount1.should.be.bignumber.equal(amount2);
2.pow
MAX_UINT256 = new BN('2').pow(new BN('256')).sub(new BN('1'));
MAX_INT256 = new BN('2').pow(new BN('255)).sub(new BN('1'));
MIN_INT256 = new BN('2').pow(new BN('255)).mul(new BN('-1'));
3.time
const { BN, expectEvent, shouldFail, time } = require('openzeppelin-test-helpers');
var _time = (await time.latest()).add(time.duration.weeks(1));
const duration = {
seconds: function (val) { return new BN(val); },
minutes: function (val) { return new BN(val).mul(this.seconds('60')); },
hours: function (val) { return new BN(val).mul(this.minutes('60')); },
days: function (val) { return new BN(val).mul(this.hours('24')); },
weeks: function (val) { return new BN(val).mul(this.days('7')); },
years: function (val) { return new BN(val).mul(this.days('365')); },
};
before(async function () {
// 在ganache解釋的solid“now”函數中,前進到下一個塊,正確讀取時間
await time.advanceBlock();
});
time.advanceBlock()
強制挖一個塊,增加塊的高度。
time.latest()
Returns the timestamp of the latest mined block. Should be coupled with advanceBlock
to retrieve the current blockchain time.
time.latestBlock()
.返回最新塊的編號
time.increase(duration)
Increases the time of the blockchain by duration
(in seconds), and mines a new block with that timestamp.
time.increaseTo(target)
Same as increase
, but a target time is specified instead of a duration.
time.duration
Helpers to convert different time units to seconds. Available helpers are: seconds
, minutes
, hours
, days
, weeks
and years
.
4.ether
const value = ether('42');