EVMethereumBlockchainhardhat

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.

Use hardhat to test smart contract