This directory contains integration tests for the Miden client library. These tests verify the functionality of the client against a running Miden node.
- Parallel Execution: Run tests in parallel to significantly reduce total execution time
- Test Filtering: Filter tests by name patterns, categories, or exclude specific tests
- Flexible Configuration: Configurable RPC endpoints, timeouts, and parallel job counts
- Comprehensive Reporting: Detailed test results with timing statistics and progress tracking
- cargo-nextest-like Experience: Similar filtering and execution patterns as cargo-nextest
To install the integration tests binary:
make install-testsThis will build and install the miden-client-integration-tests binary to your system.
The integration tests binary can be run with various command-line options:
miden-client-integration-tests [OPTIONS]-n, --network <NETWORK>- Network preset:devnet,testnet,localhost, or a custom RPC endpoint (default:localhost). Sets defaults for all components (RPC, prover, note transport)-t, --timeout <MILLISECONDS>- Timeout for RPC requests in milliseconds (default:10000)--prover-url <URL>- Override prover endpoint. Acceptsdevnet,testnet,localhost, or a custom URL. If unset, defaults based on network--note-transport-url <URL>- Override note transport endpoint. Acceptsdevnet,testnet, or a custom URL. If unset, defaults based on network-j, --jobs <NUMBER>- Number of tests to run in parallel (default: auto-detected CPU cores, set to1for sequential execution)-f, --filter <REGEX>- Filter tests by name using regex patterns--contains <STRING>- Only run tests whose names contain this substring--exclude <REGEX>- Exclude tests whose names match this regex pattern--retry-count <NUMBER>- Number of times to retry failed tests (default:3, set to0to disable retries)--list- List all available tests without running them-h, --help- Show help information-V, --version- Show version information
Run all tests with default settings (auto-detected CPU cores):
miden-client-integration-testsRun tests sequentially (no parallelism):
miden-client-integration-tests --jobs 1Run tests with custom parallelism:
miden-client-integration-tests --jobs 8List all available tests without running them:
miden-client-integration-tests --listRun only client-related tests:
miden-client-integration-tests --filter "client"Run tests containing "fpi" in their name:
miden-client-integration-tests --contains "fpi"Exclude swap-related tests:
miden-client-integration-tests --exclude "swap"Run tests against devnet:
miden-client-integration-tests --network devnetRun tests against testnet:
miden-client-integration-tests --network testnetRun tests against devnet (auto-configures remote prover):
miden-client-integration-tests --network devnetRun tests against testnet with a local prover override:
miden-client-integration-tests --network testnet --prover-url localhostRun tests against a custom RPC endpoint with timeout:
miden-client-integration-tests --network http://192.168.1.100:57291 --timeout 30000Complex example: Run non-swap tests in parallel excluding swap tests:
miden-client-integration-tests --exclude "swap"Show help:
miden-client-integration-tests --helpThe following environment variables configure both the standalone binary and the cargo test generated wrappers:
TEST_MIDEN_NETWORK- Network preset:devnet,testnet,localhost, or a custom RPC endpoint URL (default:localhost). Sets defaults for all componentsTEST_MIDEN_RPC_URL- Overrides the RPC endpoint from the network presetTEST_MIDEN_PROVER_URL- Overrides the prover:devnet,testnet,localhost, or a custom URL (default: derived from network)TEST_MIDEN_NOTE_TRANSPORT_URL- Overrides note transport:devnet,testnet, or a custom URL (default: derived from network)MIDEN_TEST_TIMEOUT- Test timeout in milliseconds (default:10000)
| Network | RPC | Prover | Note Transport |
|---|---|---|---|
testnet |
rpc.testnet.miden.io |
tx-prover.testnet.miden.io |
transport.miden.io |
devnet |
rpc.devnet.miden.io |
tx-prover.devnet.miden.io |
transport.devnet.miden.io |
localhost |
localhost:57291 |
localhost | (none) |
Any individual env var overrides the corresponding component from the preset. For example:
# Use testnet defaults but force local prover
TEST_MIDEN_NETWORK=testnet TEST_MIDEN_PROVER_URL=localhost cargo test
# Use devnet RPC with a custom note transport
TEST_MIDEN_NETWORK=devnet TEST_MIDEN_NOTE_TRANSPORT_URL=http://localhost:57292 cargo testFor the standalone binary, CLI flags (--network, --prover-url, --note-transport-url, --timeout) take precedence over environment variables.
The integration tests cover several categories:
- Client: Basic client functionality, account management, and note handling
- Custom Transaction: Custom transaction types and Merkle store operations
- FPI: Foreign Procedure Interface tests
- Network Transaction: Network-level transaction processing
- Onchain: On-chain account and note operations
- Swap Transaction: Asset swap functionality
- AggLayer: AggLayer bridge integration (GER updates, bridge-in/out)
AggLayer tests verify the bridge integration flow: GER updates, faucet registration, bridge-in (claiming), and bridge-out.
AggLayer tests support two modes, depending on whether the node has agglayer accounts pre-deployed at genesis:
-
Empty genesis (runtime setup): All accounts (bridge admin, GER manager, bridge, faucet) are created at runtime. This is the default and works against any node started with
make start-node. -
Complete genesis (pre-deployed): Agglayer accounts are included in the genesis block. Start the node with
make start-node-agglayer, then point the tests at the.macfiles:
# Start node with agglayer genesis accounts
make start-node-agglayer
# Run genesis-aware tests
AGGLAYER_ACCOUNTS_DIR=./data/ miden-client-integration-tests --contains "agglayer"AGGLAYER_ACCOUNTS_DIR- Path to directory containing agglayer.macaccount files. Setting it switches the agglayer tests to complete-genesis mode (otherwise they default to runtime setup). The node writes these files to./data/when started withAGGLAYER_GENESIS=1. On devnet, this would point to wherever the devnet account files are stored.
When the node is started with make start-node-agglayer (or AGGLAYER_GENESIS=1), the following files are written to the data directory:
bridge_admin.mac- Bridge admin wallet (includes secret key)ger_manager.mac- GER manager wallet (includes secret key)bridge.mac- AggLayer bridge account (no secret key, NoAuth)agglayer_faucet.mac- AggLayer faucet account (no secret key, NoAuth)
The genesis faucet uses a deterministic test origin token address (0xAAAA...AA) and is pre-registered in the bridge's faucet registry.
The same tests work against devnet by setting AGGLAYER_ACCOUNTS_DIR to the directory containing devnet-specific .mac files and using the appropriate RPC endpoint:
AGGLAYER_ACCOUNTS_DIR=/path/to/devnet/accounts \
miden-client-integration-tests --network devnet --contains "agglayer"The integration tests use an automatic code generation system to create both cargo nextest compatible tests and a standalone binary. Test functions that start with test_ are automatically discovered during build time and used to generate:
- Individual
#[tokio::test]wrappers - These allow the tests to be run using standardcargo testorcargo nextest runcommands - Programmatic test access - A
Vec<TestCase>that enables the standalone binary to enumerate and execute tests dynamically with custom parallelism and filtering
The discovery system:
- Scans all
.rsfiles in thesrc/directory recursively - Identifies functions named
test_*(supportingpub async fn test_*,async fn test_*, etc.) - Generates test registry and integration test wrappers automatically
This dual approach allows the same test code to work seamlessly with both nextest (for development) and the standalone binary (for CI/CD and production testing scenarios), ensuring consistent behavior across different execution environments.
To add a new integration test:
- Create a public async function that starts with
test_ - The function should take a
ClientConfigparameter - The function should return
Result<()> - Place the function in any
.rsfile undersrc/
Example:
pub async fn test_my_feature(client_config: ClientConfig) -> Result<()> {
let (mut client, authenticator) = client_config.into_client().await?;
// test logic here
}The build system will automatically discover this function and include it in both the test registry and generate tokio test wrappers.
This project is MIT licensed.