使用hardhat开发以太坊智能合约-测试合约_智能合约测试方法
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
Web3工具网站【点我访问】 现已上线欢迎使用如有好的意见和建议也欢迎反馈。
本系列课程
上一章我们讲解了如何搭建基本的hardhat开发环境这一章我们来讲一下如何测试、部署合约
特别提醒本系列教程默认你已经掌握了solidity的开发技能如果你对solidity还不能完全理解请先移步solidity的相关教程
1、编译合约
我们使用vscode打开项目在菜单左侧打开contracts目录可以发现里面已经有一个Lock.sol文件了这个是hardhat为我们准备的测试的合约文件
打开Lock.sol文件
可以看到其实是一个很简单的逻辑里面定义了2个变量还有一个事件以及一个调用方法整个合约要实现的就是当事件满足一定条件的时候才可以从合约账号提现
下面我们使用hardhat提供的命令对合约文件进行编译
npx hardhat compile
hardhat会帮我们编译contracts目录下面的所有合约文件
这时候我们可以看到在控制台已经输出了编译日志如果编译不成功会提示相应的错误信息
在我们的项目目录里同时也会生成一些新的文件如上图所示其中cache目录为缓存文件artifacts目录下的build-info目录存放的是构建项目的信息contracts下面存放的是编译的每个合约对应的abi接口信息
2、测试合约
通过上面的操作我们已经成功的编译了合约文件下面我们来对合约文件进行测试一个好的测试流程可以避免我们的合约出现一些严重的bug特别是在区块链上一旦合约部署上去就无法再次更新所以我们在正式上线之前必须将合约完全测试一遍
2.1 测试脚本介绍
我们回到vscode打开项目目录test这里已经有了一个名为Lock.js的脚本文件
让我们打开它看一下它的主要构成
代码前6行定义了几个常用的测试辅助对象其中 loadFixture可以让我们在测试中都使用相同的配置最常用的就是我们在测试类里会定义一个部署合约的方法然后在需要使用合约对象的地方通过loadFixture(function) 获取部署合约的快照对象
在hardhat里我们使用chaijs Chaijs官网 来进行断言测试 感兴趣的朋友可以浏览chai官网获取更多信息通过使用expect方法进行断言测试
describe("Lock", function () {})
这段代码就是标识测试的开始其中第一个参数为测试标题可以随便定义第二个参数为要执行的函数体我们在函数体里进行具体测试逻辑的编写
describe是可以嵌套使用的
所以我们一般测试会在第一个describe里定义一个合约部署方法然后在describe里嵌套 describe通过loadFixture(function) 获取相同合约部署快照
2.2 合约部署方法
回到刚刚的测试文件我们继续阅读代码
async function deployOneYearLockFixture() {
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
const ONE_GWEI = 1_000_000_000;
const lockedAmount = ONE_GWEI;
const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount] = await ethers.getSigners();
const Lock = await ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
return { lock, unlockTime, lockedAmount, owner, otherAccount };
}
这部分代码定义了一个合约部署方法其中
const [owner, otherAccount] = await ethers.getSigners();
第一个owner 即为我们部署合约的账号可以通过加入更多字段接受返回获取其他的账号信息如otherAccount这个定义
const Lock = await ethers.getContractFactory("Lock");
这句代码创建了一个合约对象Lock注意括号内的Lock对应的是合约文件内定义的名称即
contract Lock {}
请不要错把合约文件名当成该参数否则会报错
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
通过deploy方法进行合约部署括号内为合约部署时所需的初始化值如果合约不需要可以不填写
2.3 测试方法
describe("Deployment", function () {
it("Should set the right unlockTime", async function () {
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
expect(await lock.unlockTime()).to.equal(unlockTime);
});
});
在describe里使用 it进行测试第一个参数为测试描述第二个参数为具体方法实现
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
获取合约创建快照对象从对象中获取到合约对象以及合约部署方法里定义的解锁时间
expect(await lock.unlockTime()).to.equal(unlockTime);
使用expect进行断言判断合约对象里面存储的解锁时间是否与合约部署方法里定义的解锁时间相等
2.4 测试演示
接下来让我们运行测试来看一下测试的结果
使用如下命令来进行合约测试
npx hardhat test
从图中打印的信息我们可以清晰的看出测试结果值得注意点是打印也是具有层级的这个是因为我们循环嵌套使用describe产生的效果通过嵌套使用可以让我们测试结果变得更为清晰推荐大家使用
通过本章的学习我们了解了合约是如何进行测试的以及测试需要注意的一些事项接下来我们会讲解如何进行合约的部署以及网络的选择小伙伴们我们下节课见咯