Tests
Testing on Foundry is done using forge
. Here we'll learn how to perform basic and more advanced testing and to leverage unique functionality such as cheatcodes.
Forge can run your tests with the forge test
command. All tests are written in Solidity.
Forge will look for the tests anywhere in your source directory. Any contract with a function that starts with test
is considered to be a test. Usually, tests will be placed in test/
by convention and end with .t.sol
.
Here's an example of running forge test
in a freshly created project, that only has the default test:
$ forge test
No files changed, compilation skipped
Running 2 tests for test/Counter.t.sol:CounterTest
[PASS] testIncrement() (gas: 28312)
[PASS] testSetNumber(uint256) (runs: 256, μ: 27376, ~: 28387)
Test result: ok. 2 passed; 0 failed; finished in 24.43ms
You can also run specific tests by passing a filter:
$ forge test --match-contract ComplicatedContractTest --match-test testDeposit
Compiling 7 files with 0.8.10
Solc 0.8.10 finished in 4.20s
Compiler run successful
Running 2 tests for test/ComplicatedContract.t.sol:ComplicatedContractTest
[PASS] testDepositERC20() (gas: 102237)
[PASS] testDepositETH() (gas: 61458)
Test result: ok. 2 passed; 0 failed; finished in 1.05ms
This will run the tests in the ComplicatedContractTest
test contract with testDeposit
in the name.
Inverse versions of these flags also exist (--no-match-contract
and --no-match-test
).
You can run tests in filenames that match a glob pattern with --match-path
.
$ forge test --match-path test/ContractB.t.sol
No files changed, compilation skipped
Running 1 test for test/ContractB.t.sol:ContractBTest
[PASS] testExample() (gas: 257)
Test result: ok. 1 passed; 0 failed; finished in 492.35µs
The inverse of the --match-path
flag is --no-match-path
.
Logs and traces
The default behavior for forge test
is to only display a summary of passing and failing tests. You can control this behavior by increasing the verbosity (using the -v
flag). Each level of verbosity adds more information:
- Level 2 (
-vv
): Logs emitted during tests are also displayed. That includes assertion errors from tests, showing information such as expected vs actual. - Level 3 (
-vvv
): Stack traces for failing tests are also displayed. - Level 4 (
-vvvv
): Stack traces for all tests are displayed, and setup traces for failing tests are displayed. - Level 5 (
-vvvvv
): Stack traces and setup traces are always displayed.
Watch mode
Forge can re-run your tests when you make changes to your files using forge test --watch
.
By default, only changed test files are re-run. If you want to re-run all tests on a change, you can use forge test --watch --run-all
.