用 JavaScript 写测试用例
【Testing】NodeJS 单元测试自动化_哔哩哔哩_bilibili(Mocha和chai学习 可以单独学习了解下 与合约测试无关只是基于它进行了升级)
Truffle 使用 Mocha 测试框架和 Chai 进行断言,为您提供一个可靠的框架,从中编写 JavaScript 测试。让我们深入了解 Truffle 如何在 Mocha 的基础上构建,让您的合同测试变得轻而易举。
注意:如果您不熟悉如何在 Mocha 中编写单元测试,请在继续之前查看 Mocha 的文档。
chai断言
用于判断 具体形式分为以下三种可以随便选一种应用
Should
chai.should();
foo.should.be.a('string');
foo.should.equal('bar');
foo.should.have.lengthOf(3);
tea.should.have.property('flavors')
.with.lengthOf(3);
Expect
var expect = chai.expect;
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
expect(foo).to.have.lengthOf(3);
expect(tea).to.have.property('flavors')
.with.lengthOf(3);
Assert
var assert = chai.assert;
assert.typeOf(foo, 'string');
assert.equal(foo, 'bar');
assert.lengthOf(foo, 3)
assert.property(tea, 'flavors');
assert.lengthOf(tea.flavors, 3);
使用 contract() 而不是 describe()
从结构上讲,你的测试应该与 Mocha 的测试基本保持不变:你的测试应该存在于目录中,它们应该以扩展结尾,并且它们应该包含 Mocha 将识别为自动化测试的代码。Truffle 测试与 Mocha 的不同之处在于功能:此功能的工作原理与 Truffle 的洁净室功能完全相同。它的工作原理如下:./test``.js``contract()``describe()
-
在运行每个函数之前,您的合约会重新部署到正在运行的以太坊客户端,以便其中的测试以干净的合约状态运行。
contract()
-
该函数提供您的以太坊客户端提供的帐户列表,您可以使用它来编写测试。
contract()
由于 Truffle 在引擎盖下使用 Mocha,因此您仍然可以在不需要 Truffle 洁净室功能时运行正常的 Mocha 测试。describe()
在测试中使用合约抽象
合约抽象是使 JavaScript 的合约交互成为可能的基础(它们基本上是我们的磁通电容器)。由于 Truffle 无法检测您需要在测试中与哪些合同进行交互,因此您需要明确要求提供这些合同。您可以使用 Truffle 提供的方法执行此操作,该方法允许您为特定 Solidity 合约请求可用的合约抽象。正如您将在下面的示例中看到的那样,您可以使用此抽象来确保您的合约正常工作。artifacts.require()
有关使用合约抽象的更多信息,请参见与合约交互部分。
使用 artifacts.require()
在测试中使用与在迁移中使用它的方式相同;您只需要传递合同的名称即可。有关详细用法,请参阅迁移部分中的 artifacts.require() 文档。artifacts.require()
使用 web3
每个测试文件中都有一个实例可用,配置为正确的提供程序。所以打电话就是有效的!web3``web3.eth.getBalance
例子
用.then
这是MetaCoin Truffle Box中提供的示例测试。请注意该函数的使用,用于指定可用以太坊账户的数组,以及我们用于直接与合约交互的用途。contract()``accounts``artifacts.require()
文件:./test/metacoin.js
const MetaCoin = artifacts.require(“MetaCoin”);
contract(“MetaCoin”, accounts => {
it(“should put 10000 MetaCoin in the first account”, () =>
MetaCoin.deployed()
.then(instance => instance.getBalance.call(accounts[0]))
.then(balance => {
assert.equal(
balance.valueOf(),
10000,
“10000 wasn’t in the first account”
);
}));
it(“should call a function that depends on a linked library”, () => {
let meta;
let metaCoinBalance;
let metaCoinEthBalance;
return MetaCoin.deployed()
.then(instance => {
meta = instance;
return meta.getBalance.call(accounts[0]);
})
.then(outCoinBalance => {
metaCoinBalance = outCoinBalance.toNumber();
return meta.getBalanceInEth.call(accounts[0]);
})
.then(outCoinBalanceEth => {
metaCoinEthBalance = outCoinBalanceEth.toNumber();
})
.then(() => {
assert.equal(
metaCoinEthBalance,
2 * metaCoinBalance,
"Library function returned unexpected function, linkage may be broken"
);
});
});
it(“should send coin correctly”, () => {
let meta;
// Get initial balances of first and second account.
const account_one = accounts[0];
const account_two = accounts[1];
let account_one_starting_balance;
let account_two_starting_balance;
let account_one_ending_balance;
let account_two_ending_balance;
const amount = 10;
return MetaCoin.deployed()
.then(instance => {
meta = instance;
return meta.getBalance.call(account_one);
})
.then(balance => {
account_one_starting_balance = balance.toNumber();
return meta.getBalance.call(account_two);
})
.then(balance => {
account_two_starting_balance = balance.toNumber();
return meta.sendCoin(account_two, amount, { from: account_one });
})
.then(() => meta.getBalance.call(account_one))
.then(balance => {
account_one_ending_balance = balance.toNumber();
return meta.getBalance.call(account_two);
})
.then(balance => {
account_two_ending_balance = balance.toNumber();
assert.equal(
account_one_ending_balance,
account_one_starting_balance - amount,
"Amount wasn't correctly taken from the sender"
);
assert.equal(
account_two_ending_balance,
account_two_starting_balance + amount,
"Amount wasn't correctly sent to the receiver"
);
});
});
});
此测试将产生以下输出:
Contract: MetaCoin
√ should put 10000 MetaCoin in the first account (83ms)
√ should call a function that depends on a linked library (43ms)
√ should send coin correctly (122ms)
3 passing (293ms)
使用 async/await
下面是一个类似的示例,但使用 async/await 表示法:
const MetaCoin = artifacts.require(“MetaCoin”);
contract(“2nd MetaCoin test”, async accounts => {
it(“should put 10000 MetaCoin in the first account”, async () => {
let instance = await MetaCoin.deployed();
let balance = await instance.getBalance.call(accounts[0]);
assert.equal(balance.valueOf(), 10000);
});
it(“should call a function that depends on a linked library”, async () => {
let meta = await MetaCoin.deployed();
let outCoinBalance = await meta.getBalance.call(accounts[0]);
let metaCoinBalance = outCoinBalance.toNumber();
let outCoinBalanceEth = await meta.getBalanceInEth.call(accounts[0]);
let metaCoinEthBalance = outCoinBalanceEth.toNumber();
assert.equal(metaCoinEthBalance, 2 * metaCoinBalance);
});
it(“should send coin correctly”, async () => {
// Get initial balances of first and second account.
let account_one = accounts[0];
let account_two = accounts[1];
let amount = 10;
let instance = await MetaCoin.deployed();
let meta = instance;
let balance = await meta.getBalance.call(account_one);
let account_one_starting_balance = balance.toNumber();
balance = await meta.getBalance.call(account_two);
let account_two_starting_balance = balance.toNumber();
await meta.sendCoin(account_two, amount, { from: account_one });
balance = await meta.getBalance.call(account_one);
let account_one_ending_balance = balance.toNumber();
balance = await meta.getBalance.call(account_two);
let account_two_ending_balance = balance.toNumber();
assert.equal(
account_one_ending_balance,
account_one_starting_balance - amount,
"Amount wasn't correctly taken from the sender"
);
assert.equal(
account_two_ending_balance,
account_two_starting_balance + amount,
"Amount wasn't correctly sent to the receiver"
);
});
});
此测试将生成与上一个示例相同的输出。
指定测试
您可以将正在执行的测试限制为特定文件,如下所示:
truffle test ./test/metacoin.js
有关详细信息,请参阅完整的命令参考。
高深
Truffle 允许您访问 Mocha 的配置,以便您可以更改 Mocha 的行为方式。有关详细信息,请参阅项目配置部分。
TypeScript 文件支持
Truffle 现在支持保存为 TypeScript 文件的测试。有关更多信息,请参阅使用 JavaScript 编写测试指南。.ts