Truffle测试框架

2018年06月08日 19:01:19 tianlongtc 阅读数 1000
 
Truffle 有一个标准的自动化测试框架,让你可以非常方便地测试您的合约.这个框架允许您以两种不同的方式编写简单可控的测试:
      1. 在JavaScript中, 用于执行来自外部世界的合约,就像您的应用程序一样。
      2. 在Solidity中, 用于在先进的,裸露的金属场景中执行您的合约。
两种测试方式都有其优点和缺点,请参阅下面两部分。
 
  • 使用 Javascript 编写测试
Truffle 使用 Mocha 测试框架 和 Chai 断言来给你提供一个可靠的框架编写JavaScript测试,让我们深入研究一下,看看Truffle 是如何构建在Mocha之上,让你可以轻松地测试你的合约的。
注意:如果您不熟悉在Mocha上做单元测试,请在继续之前查看一下 Mocha的文档。
使用contract()代替describe()
从结构上说,您的测试文件应该与Mocha基本保持一致: 您的测试文件应该放在 ./test 目录, 以 .js作为后缀,而且,它们应该包含Mocha能够识别的自动化测试代码。让 Truffle 和 Mocha 不一样的是这个 contract() 函数: 这个函数基本和 describe() 一样,只不过它可以启用clean-room 功能.  其过程如下:
   1. 每次contract()函数运行之前,您的合约会被重新部署到正在运行的以太坊客户端,因此测试是在一个干净的合约环境下进行的。
   2. 这个contract()函数提供一个由您的以太坊客户端生成的,可以在编写测试合约使用的账户列表。
合约抽象是 JavaScript 实现合约交互的基础。因为Truffle 无法检测出在测试中需要与哪些合约进行交互,所以您需要明确地指出这些合约。您可以使用一个由Truffle提供的方法 artifacts.require()来做这些事情,它可以让您为一个特定的合约,请求一个可用的合约抽象。就如您在下面的例子中所看到的,然后您可以使用这个抽象来确保您的合约工作正常。 有关使用合约抽象的更多信息,查看与你的合约交互章节。
使用artifacts.require()
在测试中使用artifacts.require()的方式和在迁移中使用的方式相同,您只需要指定合约名称.更多信息,请查看artifacts.require()
使用web3
每个测试文件都有一个配置了正确提供者的web3实例,所以web3.eth.getBalance直接调用就行了。
实例
使用.then
这里是一个由 Metacoin Truffle Box提供的测试案例. 注意这 contract() 函数的使用, 这个 accounts 数组是指定的可用的以太坊账户,  artifacts.require() 则是为了和合约直接交互用的.
文件:./test/metacoin.js
运行truffle test ./test/metacoin.js输出如下内容:
使用ASYNC/AWAIT

这是个类似的实例,只不过使用的是async/await

指定测试文件

我们通过如下命令限制执行测试的文件:

更多命令请参考command reference

进阶

Truffle提供访问Mocha配置的能力,因此你可以通过改变Mocha配置来改变Mocha的行为,更多信息,请参考project configuration
  • 使用Solidity编写测试
Solidity测试合约以.sol文件格式与javascript测试文件一起工作.当truffle test运行时,它们将作为测试合约的独立测试套件包括在内.这些合约保留了JavaScript测试的所有优点:即每个测试套件都有一个洁净室环境,可以直接访问已部署的合同以及拥有导入任何合约依赖的能力.除了这些功能外,Truffle的Solidity测试框架还考虑到如下问题:
  1. Solidity测试不需要继承任何合约,这让你的测试尽可能的小,同时你也能对你写的合约能有一个完全的控制。
  2. Solidity不受任何断言库的影响,Truffle提供了默认的断言库,而且您可以按需修改此断言库。
  3. 您可以针对任何以太坊客户端运行您的Solidity测试。

实例

在深入探索之前,我们来看一个示例Solidity测试。以下是truffle unbox metacoin为您提供的示例Solidity测试:

运行truffle test ./test/TestMetacoin.sol输出如下:

测试框架
为了更好的理解发生了什么,让我们进入更深层的讨论
断言
你的断言方法,比如Assert.equal(),是由truffle/Assert.sol库提供的。这是默认的断言库,您也可以包含您自己的断言库,只要这个库能通过触发正确的断言事件与Truffle的测试运行器进行交互。您能在Assert.sol找到所有能用的断言方法。
部署地址
您通过truffle/DeployedAddresses.sol部署的合约(合约会作为migration的一部分被部署)是可用的,这是由truffle提供的并且会在每个套件提供洁净室测试运行环境之前被重新编译和重新链接。这个库以如下形式为您部署的所有合约提供函数:
DeployedAddress.<contract name>();这将返回一个您能用来访问合约的地址,具体使用方法请参考上面的实例。为了使用部署的合约,您必须将合约代码引入到你的测试套件里去,注意import “../contracts/MetaCoin.sol”;在这个实例中,import导入的是./test目录下与之相关的合约,然后使用合约将地址强转为Metacoin类型。
测试合约名称
所有的测试合约必须以Test开头,使用一个大写的T。这使之区别于测试帮助类和项目合约,让测试器知道哪些合约代表测试套件。
测试方法名称
跟测试合约名一样,所有的测试方法名必须以test开头(小写的),每个测试方法作为单个交易以出现在测试文件中的顺序执行。由truffle/Assert.sol提供的断言函数出发时间,测试运行器评估改事件以确定测试结果。断言函数返回一个表示断言结果的布尔值,您可以使用它提前从测试中返回以防止执行错误(如Ganache或Truffle Develop将会暴露的错误)。
钩子前后
truffle提供给您许多测试钩子,在下面的实例中展示。这些钩子是beforeAll,beforeEach,afterAll和afterEach,这与Mocha在JavaScript测试中提供的钩子是一样的。您能使用这些钩子在测试前后或者在每个测试套件运行前后做setup和teardown的操作。和测试函数一样,每个钩子都是作为单个交易运行的。请注意,一些复杂的测试需要执行大量的设置,这可能会溢出单个事务的gas限制;您可以通过创建许多带有后缀的钩子来绕过这个限制,就像下面例子所描述的:
这个测试合约也展示了您的测试函数和hook函数可以共享合约状态。您可以在测试之前设置合约数据,在测试中使用这些数据以及重置数据以准备下一个测试。注意,就像您的JavaScript测试一样,您的下一个测试函数将以之前运行的测试函数状态继续运行。
高级功能

Solidity 测试具有一些高级功能,可以让你测试特殊用例。

测试异常

您可以很容易地测试你的合同是否应该引发一个异常(例如require()/assert()/revert()语句;throw在早期的Solidity版本上抛出。这个主题首先由作者Simon de la Rouviere在他的教程“在Truffle Solidity测试中抛出异常”中提出。注:该教程大量使用弃用的关键词throw来抛出异常,并从Solidity v0.4.13版本开始被require(),assert()和revert()所取代。

测试以太坊交易

您也可以测试您的合同如何对接收Ether做成出反应,并在Solidity中编写该交互脚本。为了达到这个目的,您的测试应该有一个叫initialBalance,返回值为uint的公有函数。这可以直接写作一个方法或者公用变量,就像下例所示。当您的测试合约部署到网络上,Truffle将从您的测试账户发送大量的Ether到您的测试合约。然后,您的测试合约可以使用这些Ether来在您的合约测试中编写与以太坊的交互。注意:initialBalance是可选的,不是必须的。

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

来源:区块链兄弟

原文链接:

http://www.blockchainbrother.com/article/2082

Truffle测试框架的更多相关文章

  1. mocha测试框架-truffle

    https://mochajs.org/
学习网址:
https://www.jianshu.com/p/9c78548caffa
https://www.jb51.net/article/10646 ...

  2. Go语言打造以太坊智能合约测试框架(level1)

    传送门: 柏链项目学院 Go语言打造以太坊智能合约测试框架 前言 这是什么? 这是一个基于go语言编写的,自动化测试以太坊智能合约的开发框架,使用此框架,可以自动化的部署合约,自动测试合约内的功能函数 ...

  3. phpunit 测试框架安装

    PHPUnit是一个轻量级的PHP测试框架.它是在PHP5下面对JUnit3系列版本的完整移植,是xUnit测试框架家族的一员(它们都基于模式先锋Kent Beck的设计).来自百度百科 一.下载wg ...

  4. 某互联网后台自动化组合测试框架RF+Sikuli+Python脚本

    某互联网后台自动化组合测试框架RF+Sikuli+Python脚本 http://www.jianshu.com/p/b3e204c8651a 字数949 阅读323 评论1 喜欢0 一.**Robo ...

  5. selenium测试框架使用xml作为对象库

    之前已经写过一篇: selenium测试框架篇,页面对象和元素对象的管理 上次使用的excel作为Locator对象管理,由于excel处理不够方便,有以下缺点: 不能实现分page 加载Locato ...

  6. selenium 测试框架中使用grid

    之前的测试框架:http://www.cnblogs.com/tobecrazy/p/4553444.html 配合Jenkins可持续集成:http://www.cnblogs.com/tobecr ...

  7. selenium测试框架篇,页面对象和元素对象的管理

    前期已经做好使用Jenkins做buildhttp://www.cnblogs.com/tobecrazy/p/4529399.html 做自动化框架,不可避免的就是对象库. 有一个好的对象库,可以让 ...

  8. Junit测试框架 Tips

    关于Junit测试框架使用的几点总结: 1.Junit中的测试注解: @Test →每个测试方法前都需要添加该注解,这样才能使你的测试方法交给Junit去执行. @Before →在每个测试方法执行前 ...

  9. Python几种常用的测试框架

    一.测试的常用规则 一个测试单元必须关注一个很小的功能函数,证明它是正确的: 每个测试单元必须是完全独立的,必须能单独运行.这样意味着每一个测试方法必须重新加载数据,执行完毕后做一些清理工作.通常通过 ...

随机推荐

  1. node - path路径

    1.node命令路径与js文件路径 node命令路径为node命令所执行的目录,js文件路径指的是你要运行的js所在的目录. 如上图所示: server.js路径为E:\zyp: node命令路径我们 ...

  2. Vue中遍历数组的新方法

    1.foreach foreach循环对不能使用return来停止循环 search(keyword){ var newList = [] this.urls.forEach(item =>{ ...

  3. AngularJS入门教程之数据绑定原理详解

    这篇文章主要是写给新手的,是给那些刚刚开始接触Angular,并且想了解数据帮定是如何工作的人.如果你已经对Angular比较了解了,那强烈建议你直接去阅读源代码. Angular用户都想知道数据绑定 ...

  4. Go微服务 grpc/protobuf

    了解grpc/protobuf gRPC是一个高性能.通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers ...

  5. 【转】Java8中list转map方法总结

    https://blog.csdn.net/zlj1217/article/details/81611834 背景在最近的工作开发之中,慢慢习惯了很多Java8中的Stream的用法,很方便而且也可以 ...

  6. electronic初体验

    面试被问到electronic,就是之前了解electronic打包桌面应用.哎回来就好奇捣鼓捣鼓呗!为了快速的上手去除配置的繁琐过程,直接用了electron-vue脚手架了解了下 electron ...

  7. Java 基础 线程的Runnable接口 /线程的同步方法 /同步代码块

    笔记: /**通过 Runnable接口来实现多线程 * 1. 创建一个实现runnable 接口的类 * 2. 在类中实现接口的run() 抽象方法 * 3. 创建一个runnable 接口实现类的 ...

  8. Hadoop的简单了解与安装

    hadoop 一, Hadoop  分布式 简介Hadoop  是分布式的系统架构,是  Apache  基金会顶级金牌项目 分布式是什么?学会用大数据的思想来看待和解决问题 思 想很重要 1-1 . ...

  9. resultSet.getMetaData() 获得表结构

    1.得到查询结果,一个数据集 rs = stat.executeQuery("select * from " + table_name + " limit " ...

  10. css选择器学习(一)

    1.通用选择器“*”和元素选择器 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...