0
0
BlockchainHow-ToBeginner ยท 4 min read

How to Test Smart Contracts in Solidity: Simple Guide

To test a Solidity smart contract, write test scripts using frameworks like Hardhat or Truffle that deploy the contract and check its functions. Use JavaScript or TypeScript tests with assertions to verify expected behavior automatically.
๐Ÿ“

Syntax

Testing a Solidity smart contract typically involves these steps:

  • Deploy the contract: Create a fresh instance for each test.
  • Call contract functions: Interact with the contract methods.
  • Assert expected results: Check if outputs or state changes match expectations.

Example test structure in JavaScript with Hardhat:

javascript
describe('ContractName', function () {
  let contract;

  beforeEach(async function () {
    const ContractFactory = await ethers.getContractFactory('ContractName');
    contract = await ContractFactory.deploy();
    await contract.deployed();
  });

  it('should do something expected', async function () {
    const result = await contract.someFunction();
    expect(result).to.equal(expectedValue);
  });
});
๐Ÿ’ป

Example

This example shows how to test a simple Solidity contract that stores and retrieves a number using Hardhat and Mocha testing framework.

solidity and javascript
// Solidity contract: SimpleStorage.sol
pragma solidity ^0.8.0;

contract SimpleStorage {
    uint256 private storedNumber;

    function set(uint256 num) public {
        storedNumber = num;
    }

    function get() public view returns (uint256) {
        return storedNumber;
    }
}

// JavaScript test: test/SimpleStorage.js
const { expect } = require('chai');

describe('SimpleStorage', function () {
  let simpleStorage;

  beforeEach(async function () {
    const SimpleStorage = await ethers.getContractFactory('SimpleStorage');
    simpleStorage = await SimpleStorage.deploy();
    await simpleStorage.deployed();
  });

  it('should return 0 initially', async function () {
    expect(await simpleStorage.get()).to.equal(0);
  });

  it('should store and return the correct number', async function () {
    await simpleStorage.set(42);
    expect(await simpleStorage.get()).to.equal(42);
  });
});
Output
SimpleStorage โœ“ should return 0 initially โœ“ should store and return the correct number 2 passing (XXms)
โš ๏ธ

Common Pitfalls

Common mistakes when testing smart contracts include:

  • Not deploying a fresh contract instance before each test, causing state to leak between tests.
  • Forgetting to await asynchronous calls, leading to false positives or errors.
  • Not using assertions to check results, so tests pass without verifying behavior.
  • Ignoring revert or failure cases by not testing for expected errors.

Example of a wrong test missing await:

javascript
// Wrong test (missing await)
it('should store number', function () {
  simpleStorage.set(10); // missing await
  expect(simpleStorage.get()).to.equal(10); // fails because set not completed
});

// Correct test
it('should store number', async function () {
  await simpleStorage.set(10);
  expect(await simpleStorage.get()).to.equal(10);
});
๐Ÿ“Š

Quick Reference

Tips for effective smart contract testing:

  • Use beforeEach to deploy a new contract instance for isolation.
  • Always await contract calls and transactions.
  • Test both success and failure scenarios.
  • Use assertion libraries like chai for clear checks.
  • Run tests frequently during development to catch bugs early.
โœ…

Key Takeaways

Always deploy a fresh contract instance before each test to avoid state conflicts.
Use async/await to handle contract calls and transactions properly.
Write assertions to verify contract behavior and expected results.
Test both normal and error cases to ensure contract robustness.
Use frameworks like Hardhat or Truffle for easy and automated testing.