Hardhat provides a powerful testing framework based on Mocha and Chai. Here are the core points for writing tests:
Test File Structure:
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); }); });
Core Features:
- Contract Deployment
javascriptconst Contract = await ethers.getContractFactory("ContractName"); const contract = await Contract.deploy(); await contract.deployed();
- Function Calls and Assertions
javascriptconst tx = await contract.someFunction(param1, param2); await tx.wait(); // Wait for transaction confirmation expect(await contract.someViewFunction()).to.equal(expectedValue);
- Event Listening
javascriptawait expect(contract.someFunction()) .to.emit(contract, "EventName") .withArgs(arg1, arg2);
- Transaction Revert Testing
javascriptawait expect(contract.failingFunction()) .to.be.revertedWith("Error message");
- Snapshot Functionality
javascriptconst snapshot = await ethers.provider.send("evm_snapshot", []); // Perform some operations await ethers.provider.send("evm_revert", [snapshot]);
- Time Manipulation
javascriptawait ethers.provider.send("evm_increaseTime", [3600]); // Increase by 1 hour await ethers.provider.send("evm_mine"); // Mine new block
Best Practices:
- Use
beforeEachandafterEachto manage test state - Provide clear descriptions for each test case
- Test both normal and exception paths
- Use meaningful test data
- Maintain test independence and reproducibility