Remix IDE Cheatsheet

Testing

Use this Remix IDE reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Two Testing Approaches in Remix

ApproachFile typeRunnerBest for
Solidity Unit Testing*_test.solSolidityUnitTesting pluginPure on-chain assertions, no JS tooling
JavaScript / Mocha*.test.jsRemix Script Runner (via Hardhat)Complex scenarios, ethers.js access

Solidity Unit Testing

Activating the Plugin

  1. Plugin Manager (puzzle icon) → search "Solidity Unit Testing"Activate.
  2. The plugin icon appears in the left bar.

Writing a Test File

Name the file ending in _test.sol — Remix detects it automatically.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "remix_tests.sol";          // injected by the plugin
import "../contracts/Counter.sol";

contract CounterTest {
    Counter counter;

    function beforeEach() public {
        counter = new Counter();   // fresh instance per test
    }

    function testInitialValue() public {
        Assert.equal(counter.get(), 0, "Initial value should be 0");
    }

    function testIncrement() public {
        counter.increment();
        Assert.equal(counter.get(), 1, "Should be 1 after one increment");
    }

    function testDecrementReverts() public {
        // Test that a revert is expected
        (bool success, ) = address(counter).call(
            abi.encodeWithSignature("decrement()")
        );
        Assert.equal(success, false, "Should revert when decrementing from 0");
    }
}

Assert Methods

MethodSignature
EqualAssert.equal(a, b, msg)
Not EqualAssert.notEqual(a, b, msg)
Greater ThanAssert.greaterThan(a, b, msg)
Less ThanAssert.lessThan(a, b, msg)
Ok (truthy)Assert.ok(condition, msg)

Assert supports uint, int, bool, bytes32, address, and string overloads.

Lifecycle Hooks

FunctionWhen it runs
beforeAll()Once before all tests in the contract
afterAll()Once after all tests in the contract
beforeEach()Before each individual test function
afterEach()After each individual test function

Running Tests

  1. Open the Solidity Unit Testing plugin.
  2. Select the _test.sol file from the file picker.
  3. Click Run — results appear in the plugin panel with green ✓ / red ✗.
  4. Click a failing test name to jump to the line in the editor.

JavaScript / Mocha Testing

Setup

.test.js files run through the Remix script runner with mocha, chai, and a Hardhat-style ethers shim (v6) preloaded — no npm install needed. ethers.getContractFactory pulls the ABI + bytecode from your workspace's compiled artifacts, so compile the contract first:

// tests/Counter.test.js
const { expect } = require("chai");
const { ethers } = require("hardhat");   // Remix shims hardhat-ethers over its own artifacts

describe("Counter", function () {
  let counter;

  beforeEach(async function () {
    const Counter = await ethers.getContractFactory("Counter");
    counter = await Counter.deploy();
    await counter.waitForDeployment();
  });

  it("starts at zero", async function () {
    expect(await counter.get()).to.equal(0n);
  });

  it("increments correctly", async function () {
    await (await counter.increment()).wait();
    expect(await counter.get()).to.equal(1n);
  });
});

Running JS Tests

Right-click the .test.js file in the File Explorer → Run. Output appears in the Terminal.

Testing Payable Functions

Marking a Solidity test function payable is not enough — value and sender are injected with custom transaction context NatSpec comments (/// #value: in wei, /// #sender: account-n from remix_accounts.sol) placed directly above the test:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "remix_tests.sol";
import "remix_accounts.sol";   // provides TestsAccounts
import "../contracts/Vault.sol";

contract VaultTest {
    Vault vault;

    function beforeAll() public {
        vault = new Vault();
    }

    /// #sender: account-1
    /// #value: 1000000000000000000
    function testDeposit() public payable {
        Assert.equal(msg.value, 1 ether, "test should receive 1 ether");
        Assert.equal(msg.sender, TestsAccounts.getAccount(1), "wrong sender");
        vault.deposit{value: msg.value}();
        Assert.equal(address(vault).balance, 1 ether, "vault should hold 1 ether");
    }
}
  • /// #value: <wei> — the test function must be payable to receive it.
  • /// #sender: account-n — one of the test accounts exposed by remix_accounts.sol (TestsAccounts.getAccount(n)).

Testing Events

// JS test — check an emitted event (ethers v6)
const receipt = await (await counter.increment()).wait();
const parsed  = receipt.logs.map((log) => counter.interface.parseLog(log));
const event   = parsed.find((e) => e && e.name === "Incremented");
expect(event).to.not.be.undefined;
expect(event.args.newValue).to.equal(1n);