CLI
mud test

mud test

This command runs the tests in a MUD project. Internally, it runs the following steps:

  1. Starts an anvil (opens in a new tab) instance.
  2. Deploys the World and all related Systems using mud deploy.
  3. Runs tests using forge test (opens in a new tab) and passes the deployed world address to the tests via the WORLD_ADDRESS environment variable.

Command line options

OptionMeaningTypeDefault value
--versionShow version numberbooleanfalse
--configPathPath to the config filestringmud.config.ts
--printConfigPrint the resolved configbooleanfalse
--saveDeploymentSave the deployment info to a filebooleantrue
--profileThe foundry profile to usestringlocal
--srcDirSource directorystringFoundry src directory
--skipBuildSkip rebuilding the contracts before deployingbooleanfalse
--alwaysRunPostDeployRun PostDeploy.s.sol after each deploybooleanfalse (run the script only when deploying a new World)
--portPort for the testing anvil instancenumber4242
--helpShow helpbooleanfalse

Examples

pnpm mud test

Writing MUD tests

MUD test contracts inherit from MudTest (opens in a new tab). This contract gets the World address from the $WORLD_ADDRESS environment variable and sets it as the Store address.

Line by line explanation of a test

This is an explanation of the test (opens in a new tab) for the React template (opens in a new tab) contracts.

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.21;
 
import "forge-std/Test.sol";
import { MudTest } from "@latticexyz/world/test/MudTest.t.sol";

Import the general definitions required in all MUD tests.

import { IWorld } from "../src/codegen/world/IWorld.sol";
import { Tasks, TasksData } from "../src/codegen/index.sol";

Import the definitions required for this test, the World we can access and the tables we'll use.

contract TasksTest is MudTest {
  function testWorldExists() public {

MUD tests are Foundry tests (opens in a new tab). Any public function that starts with test is a test that gets executed.

    uint256 codeSize;
    address addr = worldAddress;

The World address comes from the MudTest (opens in a new tab).

    assembly {
      codeSize := extcodesize(addr)
    }
    assertTrue(codeSize > 0);
  }

Use extcodesize (opens in a new tab) to get the size of the World contract. If the deploy process failed, there wouldn't be any code there.

  function testTasks() public {
    // Expect task to exist that we created during PostDeploy script
    TasksData memory task = Tasks.get("1");

Use the structure for a table entry's values that is created as part of code generation.

    assertEq(task.description, "Walk the dog");
    assertEq(task.completedAt, 0);

Verify the information that is prepopulated by the PostDeploy.s.sol script (opens in a new tab).

    // Expect the task to be completed after calling completeTask from our TasksSystem
    IWorld(worldAddress).completeTask("1");

Call a System to modify the table data.

    assertEq(Tasks.getCompletedAt("1"), block.timestamp);
  }
}

Verify that the call changed the data correctly.