5. 用js测试

用 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

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值