Use hardhat to test smart contract
January 18, 2025
Background
Did you hear about hardhat? Already hardhat is used to automate development for smart contract in EVM(Ethreum Vitrual Machine). It provides a lot of convenient tools for test, deploy, and task. The user can install and use any plugin to advance using.
While working, I should use hardhat. Because I usually work on smart contracts. I realized it is better that study hardhat and adapt on my work.
I will talk about deploy and test without implementing smart contract by solidity.
Test
loadFixture
For test, hardhat takes mocha and chai frameworks. It's used brodally in JavaScript.
Basically, you get loadFixture
from hardhat-toolbox/network-helpers
. loadFixture
is very useful function to test. Following some example.
import {
loadFixture,
} from "@nomicfoundation/hardhat-toolbox/network-helpers";
describe("Contract", ()=>{
const deployContractModule = ()=> {
const contract = hre.ethers.deployContract("contract");
return {contract}
}
describe("Func1", ()=> {
it("Test1", ()=> {
const {contract} = loadFixture(deployContractModule);
expect(contract.func()).equal(value)
})
})
describe("Func2", ()=> {
it("Test2", ()=>{
const {contract} = loadFixture(deployContractModule);
expect(contract.func()).equal(value)
})
})
})
It enables you reuse deployed contract.
If you already know mocha, you guess that loadFixture
can be replace with beforeAll
or beforeEach
.
But there are some problem. The contract will be deployed in virtual network, and it takes some times.
In every test, if you use beforeEach
to deploy and init contract, it takes several times at each call.
loadFixture
deploy contracts once by a function you write and return those contracts at each call in your test code.
time
time
is powerful tool in hardhat.
You can take time travel with time
in hardhat.
So it can be usefull when you implement contracts with block.timestamp
in solidity.
time
is synchronized with block time in hardhat node.
You can understand that hardhat node is a blockchain in your localhost.
time
use UNIX time as same with EVM. The unit of time is seconds.
So if you use JavaScript, maybe I guess you use Date
Object, you should divide time with 1,000.
time
supports increase
and increaseTo
methods.
After you call these methods, the block time in your local node also points same time.
Unfortunately, time travel should head to future so reverse is not supported.
Deploy
hardhat
supports tool called Ignition
for deploying contracts.
hardhat
project take a directory for deploying scripts.
This directory locate in '{root}/ignition/module'.
And each contracts has script for deploy in that directory.
You just use hardhat ignition deploy
command in your terminal to do deploy.
buildModule
is a function supported by hardhat ignition.
You should export the instance made by buildModule
.
Following example is from hardhat document.
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("Apollo", (m) => {
const apollo = m.contract("Rocket", ["Saturn V"]);
m.call(apollo, "launch", []);
return { apollo };
});
buildModule
has some parameters.
And a parameter in buildModule
is a callback function to write code for deploy.
Deploying Function also has parameter.
Above example, you can see that, m
.
To take contract you want, just insert contract name in m.contract
call.
If it don't get contract, run command hardhat compile
.
buildModule
get contract automately.