Hardhat 提供了强大的测试框架,基于 Mocha 和 Chai,以下是编写测试的核心要点:
测试文件结构:
javascriptconst { expect } = require("chai"); const { ethers } = require("hardhat"); describe("MyContract", function () { beforeEach(async function () { const MyContract = await ethers.getContractFactory("MyContract"); this.contract = await MyContract.deploy(); await this.contract.deployed(); }); it("should return the correct value", async function () { expect(await this.contract.getValue()).to.equal(42); }); });
核心功能:
- 合约部署
javascriptconst Contract = await ethers.getContractFactory("ContractName"); const contract = await Contract.deploy(); await contract.deployed();
- 函数调用和断言
javascriptconst tx = await contract.someFunction(param1, param2); await tx.wait(); // 等待交易确认 expect(await contract.someViewFunction()).to.equal(expectedValue);
- 事件监听
javascriptawait expect(contract.someFunction()) .to.emit(contract, "EventName") .withArgs(arg1, arg2);
- 交易回滚测试
javascriptawait expect(contract.failingFunction()) .to.be.revertedWith("Error message");
- 快照功能
javascriptconst snapshot = await ethers.provider.send("evm_snapshot", []); // 执行一些操作 await ethers.provider.send("evm_revert", [snapshot]);
- 时间操作
javascriptawait ethers.provider.send("evm_increaseTime", [3600]); // 增加1小时 await ethers.provider.send("evm_mine"); // 挖掘新区块
最佳实践:
- 使用
beforeEach和afterEach管理测试状态 - 为每个测试用例提供清晰的描述
- 测试正常路径和异常路径
- 使用有意义的测试数据
- 保持测试的独立性和可重复性