使用Mocha与chai进行测试
存在于hardhat-toolbox中
1. 环境配置
• 安装 Hardhat-Deploy 插件
用于简化部署脚本管理和多网络部署:
bash
npm i -D hardhat-deploy
在 hardhat.config.js
中引入插件:
javascript
require('hardhat-deploy');
• 测试框架集成
hardhat-toolbox
已内置 Mocha(测试运行器) 和 Chai(断言库) ,无需额外安装。测试文件需放在 test/
目录下,文件名以 .test.js
结尾。
2. 单元测试(本地环境)
• 基本原则
• 覆盖所有可能的分支(如 fund
、withdraw
、refund
等涉及资产转移的关键函数)。 • 使用 describe
分组测试用例,it
定义具体测试逻辑。 • 示例结构:
js
const { expect } = require("chai");
describe("FundMe", function() {
beforeEach(async () => {
// 部署合约并初始化
const FundMeFactory = await ethers.getContractFactory("FundMe");
fundMe = await FundMeFactory.deploy();
});
it("Reverts if ETH amount is 0", async () => {
await expect(fundMe.fund()).to.be.revertedWith("Amount must be > 0");
});
});
• Mock 合约的使用
• 目的 :模拟外部依赖(如 Chainlink 喂价合约),避免测试依赖真实网络。
• 方法 :
-
创建 Mock 合约(参考 Chainlink MockV3Aggregator)。
-
在测试中部署 Mock 合约并注入到主合约中:
js
const MockAggregator = await ethers.getContractFactory("MockV3Aggregator");
mockAggregator = await MockAggregator.deploy(8, 2000e8); // 初始价格 2000
const FundMe = await ethers.getContractFactory("FundMe");
fundMe = await FundMe.deploy(mockAggregator.address);
3. 集成测试(真实网络)
• 配置测试网络
在 .env
中添加网络参数(如 Sepolia 的 RPC URL 和私钥):
ini
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
PRIVATE_KEY=0x...
在 hardhat.config.js
中配置网络:
javascript
networks: {
sepolia: {
url: process.env.SEPOLIA_RPC_URL,
accounts: [process.env.PRIVATE_KEY],
},
}
• 运行测试
使用 --network
指定网络:
bash
npx hardhat test --network sepolia
重点验证合约在真实环境下的交互(如 API 调用、Gas 消耗)。
4. 辅助工具
• Gas 消耗分析(hardhat-gas-reporter)
• 安装:
js
npm i -D hardhat-gas-reporter
```
• 配置 `hardhat.config.js`:
```javascript
require("hardhat-gas-reporter");
module.exports = {
gasReporter: {
enabled: true,
currency: "USD",
coinmarketcap: "YOUR_API_KEY" // 可选,换算为美元成本
}
};
• 运行测试时自动生成 Gas 报告。
• 测试覆盖率检查(solidity-coverage)
• 运行:
bash npx hardhat coverage
• 输出覆盖率报告,显示哪些代码未被测试覆盖。
5. 最佳实践
• 测试分类
• 单元测试 :聚焦单个函数逻辑,使用 Mock 隔离依赖。
• 集成测试 :验证多合约协作或真实网络行为。 • 断言优化
使用 Chai 的 .to.emit()
检查事件触发,或 .to.changeEtherBalance()
验证资产变化。