自动化测试

2022.2.26

主要内容

Ganache,mocha

前言

我们已经实现了合约的编译和部署的自动化,这将大大提升我们开发的效率。 但流程的自动化并不能保证我们的代码质量。质量意识是靠谱工程师的基本职业 素养,在智能合约领域也不例外:任何代码如果不做充分的测试,问题发现时通 常都已为时太晚;如果代码不做自动化测试,问题发现的成本就会越来越高。

在编写合约时,我们可以利用 remix 部署后的页面调用合约函数,进行单元 测试;还可以将合约部署到私链,用 geth 控制台或者 node 命令行进行交互测 试。但这有很大的随意性,并不能形成标准化测试流程;而且手动一步步操作, 比较繁琐,不易保证重复一致。

于是我们想到,是否可以利用现成的前端技术栈实现合约的自动化测试呢? 当然是可以的,mocha 就是这样一个 JavaScript 测试框架。

安装依赖

开始编写测试脚本之前,我们首先需要安装依赖:测试框架 mocha。当然,作为对合约的测试,模拟节点 ganache 和 web3 都是不可缺少的;不过我们在 上节课编写部署脚本时,已经安装了这些依赖(我们的 web3 依然是 1.0.0 版本)。

进行单元测试,比较重要的一点是保证测试的独立性和隔离性,所以我们并 不需要测试网络这种有复杂交互的环境,甚至不需要本地私链保存测试历史。而 ganache 基于内存模拟以太坊节点行为,每次启动都是一个干净的空白环境,所以非常适合我们做开发时的单元测试。还记得 ganache 的前身叫什么吗?就是大名鼎鼎的 testRPC。

mocha简介

mocha官网(中国)

mocha 是 JavaScript 的一个单元测试框架,既可以在浏览器环境中运行,也可以在 node.js 环境下运行。我们只需要编写测试用例,mocha 会将测试自动运行并给出测试结果。 mocha 的主要特点有:

测试脚本示例

假设我们编写了一个 sum.js,并且输出一个简单的求和函数:

这个函数非常简单,就是对输入的任意参数求和并返回结果。 如果我们想对这个函数进行测试,可以写一个 test.js,然后使用 Node.js 提 供的 assert 模块进行断言:

assert 模块非常简单,它断言一个表达式为 true。如果断言失败,就抛出 Error。

单独写一个 test.js 的缺点是没法自动运行测试,而且,如果第一个 assert 报错,后面的测试也执行不了了。

如果有很多测试需要运行,就必须把这些测试全部组织起来,然后统一执行, 并且得到执行结果。这就是我们为什么要用 mocha 来编写并运行测试。

我们利用 mocha 修改后的测试脚本如下:

里我们使用 mocha 默认的 BDD-style 的测试。describe 可以任意嵌套, 以便把相关测试看成一组测试。

describe 可以任意嵌套,以便把相关测试看成一组测试;而其中的每个 it 就代表一个测试。

每个 it("name", function() {...})就代表一个测试。例如,为了测试 sum(1, 2), 我们这样写:

编写测试的原则是,一次只测一种情况,且测试代码要非常简单。我们编写多个测试来分别测试不同的输入,并使用 assert 判断输出是否是我们所期望的。

运行测试脚本

下一步,我们就可以用 mocha 运行测试了。打开命令提示符,切换到项目目录,然后创建文件夹 test,将 test.js 放入 test 文件夹下,执行命令:

mocha 就会自动执行 test 文件夹下所有测试,然后输出如下:

这说明我们编写的 4 个测试全部通过。如果没有通过,要么修改测试代码, 要么修改 hello.js,直到测试全部通过为止。

编写合约测试脚本

测试时我们通常会把每次测试运行的环境隔离开,以保证互不影响。对应到合约测试,我们每次测试都需要部署新的合约实例,然后针对新的实例做功能测试。 Car 合约的功能比较简单,我们只要设计 2 个测试用例:

新建测试文件 tests/car.spec.js,完整的测试代码如下。

web3:0.5.0之前

部署合约

web3:0.5.0之后

部署合约