Verify your smart contracts work as intended before you deploy them by writing tests.

Testing Smart Contracts

1

Write test definitions

Write test definitions inside the /test directory, for example, test/HelloWorld.t.sol.

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

import { Test } from "forge-std/Test.sol";

contract HelloWorldTest is Test {
  function setUp() public {
      owner = makeAddr("owner");
      vm.prank(owner);
      helloWorld = new HelloWorld();
  }

  function test_HelloWorld() public {
    helloWorld.setMessage("Hello, World!");
    assertEq(helloWorld.getMessage(), "Hello, World!");
  }
}
2

Run tests

Run the tests by running the following command:

forge test --zksync

Cheatcodes

Cheatcodes allow you to manipulate the state of the blockchain during testing, allowing you to change the block number, your identity, and more.

Foundry Cheatcode Reference

Reference for all cheatcodes available in Foundry.

Cheatcode Limitations

When testing on Abstract, cheatcodes have important limitations due to how the underlying ZKsync VM executes transactions. Cheatcodes can only be used at the root level of your test contract - they cannot be accessed from within any contract being tested.

// This works ✅
function testCheatcodeAtRootLevel() public {
  vm.roll(10);                     // Valid: called directly from test
  vm.prank(someAddress);           // Valid: called directly from test
  MyContract testContract = new MyContract();
  testContract.someFunction();     // Cheatcodes not available inside this call
}

// This won't work as expected ❌
contract MyContract {
  function someFunction() public {
    vm.warp(1000);                 // Invalid: called from within a contract
  }
}

ZKsync VM Cheatcodes

Abstract’s underlying ZKsync VM provides additional cheatcodes for testing Abstract-specific functionality:

CheatcodeDescription
zkVmEnables/disables ZKsync context for transactions. Switches between EVM and zkEVM execution environments.
zkVmSkipWhen running in zkEVM context, skips the next CREATE or CALL, executing it on the EVM instead.
zkRegisterContractRegisters bytecodes for ZK-VM for transact/call and create instructions. Useful for testing with contracts already deployed on-chain.
zkUsePaymasterConfigures a paymaster for the next transaction. Enables testing paymasters for gasless transactions.
zkUseFactoryDepRegisters a factory dependency for the next transaction. Useful for testing complex contract deployments.

Fork Testing

Running your tests against a fork of Abstract testnet or mainnet allows you to test your contracts in a real environment before deploying to Abstract.

This is especially useful for testing contracts that interact with other contracts on Abstract such as those listed on the Deployed Contracts page.

To run your tests against a fork of Abstract testnet or mainnet, you can use the following command:

forge test --zksync --fork-url https://api.testnet.abs.xyz

Local Node Testing

Anvil-zksync comes installed with Foundry, and is a tool that allows you to instantiate a local node for testing purposes.

Run the following command to start the local node:

anvil-zksync

Then run your tests on the local node by running the following command:

forge test --zksync --fork-url http://localhost:8011

View all available options ↗.

Advanced Testing

View further documentation on advanced testing with Foundry-zksync: