Unit Testing

Forc provides built-in support for building and executing tests for a package.

Tests are written as free functions with the #[test] attribute. For example:

#[test]
fn test_meaning_of_life() {
    assert(6 * 7 == 42);
}

Each test function is ran as if it were the entry point for a script. Tests "pass" if they return successfully, and "fail" if they revert or vice versa while testing failure.

Building and Running Tests

We can build and execute all tests within a package with the following:

forc test

The output should look similar to this:

  Compiled library "core".
  Compiled library "std".
  Compiled library "lib_single_test".
  Bytecode size is 92 bytes.
   Running 1 tests
      test test_meaning_of_life ... ok (170.652┬Ás)
   Result: OK. 1 passed. 0 failed. Finished in 1.564996ms.

Visit the forc test command reference to find the options available for forc test.

Testing Failure

Forc supports testing failing cases for test functions declared with #[test(should_revert)]. For example:

#[test(should_revert)]
fn test_meaning_of_life() {
    assert(6 * 6 == 42);
}

Tests with #[test(should_revert)] considered to be passing if they are reverting.

Calling Contracts

Unit tests can call contract functions an example for such calls can be seen below.

contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}

To test the test_function(), a unit test like the following can be written.

#[test]
fn test_success() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == true)
}

It is also possible to test failure with contract calls as well.

#[test(should_revert)]
fn test_fail() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == false)
}

Note: When running forc test, your contract will be built twice: first without unit tests in order to determine the contract's ID, then a second time with unit tests with the CONTRACT_ID provided to their namespace. This CONTRACT_ID can be used with the abi cast to enable contract calls within unit tests.