编写 Solidity 测试脚本

编写 Solidity 测试脚本

与 JavaScript 编写的测试脚本一样,基本特性也一直,支持净室环境,可以访问任意不说过的合约。
Truffle的可靠性测试框架是基于以下想法构建的:

  • Solidity 编写的脚本不继承任何合约。这样就使得你的测试合约尽可能的小,并且给予了你对合约的所有控制权。
  • 可靠性测试不应该依赖于任何断言库。Truffle为您提供了一个默认的断言库,但是您可以根据需要随时更改这个库。
  • 您应该能够对任何 Ethereum 客户机运行您的可靠性测试。

例子

让我们看一个例子,在还没有太深入之前。下面是 truffle unbox metacoin 提供的实度测试示例:

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/MetaCoin.sol";

contract TestMetacoin {
  function testInitialBalanceUsingDeployedContract() {
    MetaCoin meta = MetaCoin(DeployedAddresses.MetaCoin());

    uint expected = 10000;

    Assert.equal(meta.getBalance(tx.origin), expected, "Owner should have 10000 MetaCoin initially");
  }

  function testInitialBalanceWithNewMetaCoin() {
    MetaCoin meta = new MetaCoin();

    uint expected = 10000;

    Assert.equal(meta.getBalance(tx.origin), expected, "Owner should have 10000 MetaCoin initially");
  }
}

你将会看到如下输出:

$ truffle test
Compiling ConvertLib.sol...
Compiling MetaCoin.sol...
Compiling truffle/Assert.sol
Compiling truffle/DeployedAddresses.sol
Compiling ../test/TestMetacoin.sol...

  TestMetacoin
    ✓ testInitialBalanceUsingDeployedContract (61ms)
    ✓ testInitialBalanceWithNewMetaCoin (69ms)

  2 passing (3s)

测试结构

为了更好的了解发生了什么,我们深入讨论下细节。

ASSERTIONS

你的断言像 Assert.equal() 是由 truffle/Assert.sol 提供给你的。这是默认的断言库,
但是只要库通过触发正确的断言事件与 Truffle 的测试运行器松散集成,就可以包含您自己的断言库。
您可以在 Assert.sol 中找到所有可用的断言函数。

DEPLOYED ADDRESSES 已发布账户

已部署合约的地址(例如,作为迁移的一部分部署的合同)可以通过 truffle/DeployedAddresses.sol 获得。
这是由Truffle提供的,并在运行每个套件之前重新编译和重新链接,
以向您的测试提供Truffle的洁净房间环境。本库以如下形式为你的所有已部署合约提供功能:

DeployedAddresses.<contract name>();

这将返回一个地址,可以用来访问合约。请参阅上面的示例测试。

为了使用已部署的契约,您必须将契约代码导入到您的测试套件中。注意 import"../contracts/ MetaCoin.sol”;
在这个例子中。这个导入是相对于存在于./test目录中的测试契约的,为了找到MetaCoin契约,它会在测试目录之外。
然后它使用该契约将地址转换为MetaCoin类型。

测试合约名

所有合约的测试必须以 test 开头,使用大写的 T 。这样的命名方式就将测试合约和普通合约区分开来了,
让测试运行器知道那个合约代表测试套件。

测试方法名

跟测试合约类似,所有的测试方法,都必须以小写单词 test 开头。每个测试方法都会被当作一个独立的交易,
根据在测试文件中定义的顺序执行。truffle/Assert.sol 提供的断言函数,测试运行程序评估触发事件以确定测试的结果。
断言函数返回一个布尔值,表示断言成功或失败,你可以使用它从测试早期返回,以防止执行错误(例如,Ganache或Truffle开发的错误将暴露)。

hooks 使用的前后

在如下例子中为你提供了许多测试 hooks 。这些 hooks 是 beforeAll 、 beforeEach 、 afterEach ,
它们是 Mocha 在 Javascript 测试中提供的相同的 hooks 。您可以使用这些 hooks 在每个测试之前和之后,
或者在每个套件运行之前和之后执行安装和拆卸操作。和测试方法一样,每个测试 hooks 都会是一个独立的交易。
您可以通过创建许多带有不同后缀的 hooks 来绕过这个限制,如下面的示例所示:

import "truffle/Assert.sol";

contract TestHooks {
  uint someValue;

  function beforeEach() {
    someValue = 5;
  }

  function beforeEachAgain() {
    someValue += 1;
  }

  function testSomeValueIsSix() {
    uint expected = 6;

    Assert.equal(someValue, expected, "someValue should have been 6");
  }
}

这个测试合约还表明,您的测试函数和hook函数都共享相同的合约状态。您可以在测试之前设置合约数据,
在测试期间使用该数据,并在测试之后重置它,为下一个测试做准备。注意,就像Javascript测试一样,
下一个测试函数将从运行的前一个测试函数的状态继续。

高级特性

Solidity 有一些新特新可以让你使用特殊的用力来测试。

异常测试

你可以很容易地测试你的合同应不应该抛出一个异常。( 例如:require()/ assert()/revert() 语句;之前的版本的 throw)。
这个话题是特约作家西蒙·德·拉·鲁维埃(Simon de la Rouviere)在他的 Truffle Solidity 测试教程中首次提出的。
本教程不推荐的关键字 throw 大量使用异常。从Solidity v0.4.13开始取而代之的是 revert()、require()和assert()。

测试以太币交易

你也可以测试你的合约是如何接收以太币的,并且用 JavaScriptSolidity 交互。为了达到这目的,你需要在
Solidity 测试脚本中写一个名为 initialBalance 的方法,并且返回 uint
这可以直接写为函数或公共变量,如下所示。当你的测试合约被部署到网络上时,Truffle将从你的测试账户发送到你的测试合约。
你的测试合约中就可以使用这个以太币来进行测试。注意,initialBalance是可选的,不是必需的。

import "truffle/Assert.sol";
import "truffle/DeployedAddresses.sol";
import "../contracts/MyContract.sol";

contract TestContract {
  // Truffle will send the TestContract one Ether after deploying the contract.
  uint public initialBalance = 1 ether;

  function testInitialBalanceUsingDeployedContract() {
    MyContract myContract = MyContract(DeployedAddresses.MyContract());

    // perform an action which sends value to myContract, then assert.
    myContract.send(...);
  }

  function () {
    // This will NOT be executed when Ether is sent. \o/
  }
}

请注意,Truffle以不执行回退函数的方式发送到测试合约,因此您仍然可以在固态测试中对高级测试用例使用回退函数。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,848评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,529评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,824评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,329评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,227评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,879评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,218评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,877评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,159评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,155评论 2 315
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,987评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,736评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,273评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,407评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,663评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,158评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,517评论 2 339

推荐阅读更多精彩内容

  • 【本文目标】 通过本文的学习和时间,你将熟悉以太坊开发框架Truffle的配置和运行,并借助Truffle完成一...
    笔名辉哥阅读 13,001评论 8 55
  • 从小到大,我对毛绒绒的东西就不太感兴趣,那些猫猫狗狗的,更是不想去触碰,但弟弟喜欢狗,见好多小伙伴家里都养了狗,就...
    白沙暮雨阅读 400评论 0 0
  • 有什么废话想讲 抓不到重点的地方 别开口学着沉默像以往 太多的问题不解 别急着问总有答案 去亲历深刻体会 什么都不...
    要多帅气的昵称呢阅读 294评论 0 0
  • 管理时间还是管理事件? 情景:没有太多时间,时间空间、精力能量都会受到影响! 日程表,按计划进行; 有截止日期的清...
    若山12369阅读 203评论 1 0
  • 你们的孩子,都不是你们的孩子, 乃是生命为自己所渴望的儿女。 他们是凭借你们而来,却不是从你们而来, 他们虽和你们...
    阿五1122阅读 361评论 0 0