Testing
This page describes how to run tests for the solx compiler and the format of test files.
Unit and CLI Tests
Run the standard Rust test suite:
# Run all tests (unit + CLI)
cargo test
# Run only unit tests
cargo test --lib
# Run only CLI/integration tests
cargo test --test cli
# Run a specific test
cargo test --test cli -- cli::bin::default
Integration Tests
The solx-tester tool runs integration tests by compiling contracts and executing them with revm.
# Build the compiler and tester
cargo build --release
# Run all integration tests
./target/release/solx-tester --solidity-compiler ./target/release/solx
# Run tests for a specific file
./target/release/solx-tester --solidity-compiler ./target/release/solx --path tests/solidity/simple/default.sol
# Run only Yul IR pipeline tests (excludes EVMLA pipeline)
./target/release/solx-tester --solidity-compiler ./target/release/solx --via-ir
# Run tests with specific optimizer settings
./target/release/solx-tester --solidity-compiler ./target/release/solx --optimizer M3B3
# Combine filters: Yul IR pipeline with M3B3 optimizer
./target/release/solx-tester --solidity-compiler ./target/release/solx --via-ir --optimizer M3B3
Filtering Options
--via-ir— Run only tests using the Yul IR pipeline (codegenY). Without this flag, both Yul IR and EVMLA pipelines are tested.--optimizer <PATTERN>— Filter by optimizer settings. Examples:M3B3— Match exact optimizer levelM^B3— Match M3 or Mz with B3M*B*— Match any M and B levels
--path <PATTERN>— Run only tests whose path contains the pattern.
Foundry and Hardhat Projects
The solx-dev tool can run tests against real-world Foundry and Hardhat projects:
# Build solx-dev
cargo build --release --bin solx-dev
# Run Foundry project tests
./target/release/solx-dev test foundry --test-config-path solx-dev/foundry-tests.toml
# Run Hardhat project tests
./target/release/solx-dev test hardhat --test-config-path solx-dev/hardhat-tests.toml
The test configurations list projects that are cloned and tested automatically. See foundry-tests.toml and hardhat-tests.toml for the full list of tested projects.
Test Collection
This section describes the format of test files used by solx-tester.
Test Types
The repository contains three types of tests:
- Upstream — Tests following the Solidity semantic test format.
- Simple — Single-contract tests.
- Complex — Multi-contract tests and vendored DeFi projects.
Test data is located in:
tests/solidity/— Solidity test contractstests/yul/— Yul test contractstests/llvm-ir/— LLVM IR test contracts
Test Format
Each test comprises source code files and metadata.
Simple tests have only one source file, and their metadata is written in comments that start with !, for example, //! for Solidity.
Complex tests use a test.json file to describe their metadata and refer to source code files.
Metadata
Metadata is a JSON object that contains the following fields:
cases— An array of test cases (described below).contracts— Used for complex tests to describe the contract instances to deploy. In simple tests, only oneTestcontract instance is deployed.
"contracts": {
"Main": "main.sol:Main",
"Callable": "callable.sol:Callable"
}
libraries— An optional field that specifies library addresses for linker:
"libraries": {
"libraries/UQ112x112.sol": { "UQ112x112": "UQ112x112" },
"libraries/Math.sol": { "Math": "Math" }
}
ignore— An optional flag that disables a test.modes— An optional field that specifies mode filters.Ystands for Yul pipeline,Efor EVM assembly pipeline. Compiler versions can be specified as SemVer ranges:
"modes": [
"Y",
"E",
"E >=0.8.30"
]
group— An optional string field that specifies a test group for benchmarking.
Test Cases
All test cases are executed in a clean context, making them independent of each other.
Each test case contains the following fields:
name— A string name.comment— An optional string comment.inputs— An array of inputs (described below).expected— The expected return data for the last input.ignore,modes— Same as in test metadata.
Inputs
Inputs specify the contract calls in the test case:
comment— An optional string comment.instance— The contract instance to call. Default:Test.caller— The caller address. Default:0xdeadbeef01000000000000000000000000000000.method— The method to call:#deployerfor the deployer call.#fallbackto perform a call with raw calldata.- Any other string is recognized as a function name. The function selector will be prepended to the calldata.
calldata— The input calldata:- A hexadecimal string:
"calldata": "0x00" - A numbers array (hex, decimal, or instance addresses). Each number is padded to 32 bytes:
"calldata": ["1", "2"]
- A hexadecimal string:
value— An optionalmsg.value, a decimal number withweiorETHsuffix.storage— Storage values to set before the call:
"storage": {
"Test.address": ["1", "2", "3", "4"]
}
expected— The expected return data:- An array of numbers:
"expected": ["1", "2"] - Extended format with
return_data,exception, andevents:
- An array of numbers:
"expected": {
"return_data": ["0x01"],
"events": [
{
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
],
"values": ["0xff"]
}
],
"exception": false
}
The expected field can be an array of objects if different expected data is needed for different compiler versions. Use compiler_version as a SemVer range in extended expected format.
Notes:
InstanceName.addresscan be used in expected, calldata, and storage fields to insert a contract instance address.- If a deployer call is not specified for an instance, it will be generated automatically with empty calldata.
Upstream Solidity Semantic Tests
These tests follow the Solidity semantic test format.
Test descriptions and expected results are embedded as comments in the test file. Lines begin with // for Solidity files. The beginning of the test description is indicated by a comment line containing ----.