Skip to content

cargo-nextest - Next-Generation Rust Test Runner Cheatsheet

cargo-nextest - Next-Generation Rust Test Runner Cheatsheet

cargo-nextest is a next-generation test runner for Rust. Its core architectural difference from cargo test is that it runs each test in its own process, which gives true isolation (one test cannot corrupt another’s global state), better parallelism, and the ability to report a test that crashes the process rather than losing the whole run. In practice it is typically 2–3x faster than cargo test on large suites, with much cleaner output, flaky-test detection, and partitioning for CI sharding.

Installation

MethodCommand
Prebuilt (fastest)cargo install cargo-nextest --locked
Binarydownload from the nextest releases
macOS (Homebrew)brew install cargo-nextest
Verifycargo nextest --version

Basic Usage

CommandDescription
cargo nextest runRun all tests
cargo nextest run -p mycrateOne package
cargo nextest run test_nameFilter by substring
cargo nextest listList tests without running
cargo nextest run --releaseRelease profile
cargo nextest run --no-fail-fastKeep going after failures

Filtering (Filtersets)

nextest has an expression language for selecting tests.

ExpressionSelects
-E 'test(auth)'Tests whose name matches auth
-E 'package(mycrate)'All tests in a package
-E 'kind(lib)'Only lib (unit) tests
-E 'binary(integration)'A specific test binary
-E 'test(a) + test(b)'Union
-E 'package(x) - test(slow)'Difference
# Run integration tests for one crate, excluding slow ones
cargo nextest run -E 'package(api) and kind(test) - test(slow)'

Flaky Test Detection

# Retry failures up to 3 times; tests that pass on retry are marked FLAKY
cargo nextest run --retries 3
ConfigEffect
--retries NRetry failed tests N times
Reported as FLAKYPassed only after a retry
Per-test overridesSet retries for specific tests in config

This distinction matters: a flaky test is a different problem from a failing test, and nextest surfaces it explicitly instead of hiding it behind a rerun.

Configuration

# .config/nextest.toml
[profile.default]
retries = 0
fail-fast = false
slow-timeout = { period = "30s", terminate-after = 2 }

[profile.ci]
retries = 2
failure-output = "immediate-final"
status-level = "skip"

[[profile.default.overrides]]
filter = 'test(integration)'
threads-required = 2
SettingPurpose
retriesDefault retry count
slow-timeoutFlag/kill tests exceeding a duration
threads-requiredReserve capacity for heavy tests
failure-outputWhen to print failure details
Profilescargo nextest run -P ci

CI Sharding

# Split the suite across 4 CI machines
cargo nextest run --partition count:1/4   # on runner 1
cargo nextest run --partition count:2/4   # on runner 2
ModeSplits by
count:N/MRound-robin by test count
hash:N/MStable hash (same test → same shard)

Output & Reporting

OptionEffect
--status-level allShow every test’s status
--failure-output immediatePrint failures as they happen
--message-format libtest-jsonMachine-readable output
--profile ciUse CI-tuned settings
JUnit outputConfigure in nextest.toml for CI reporting

Limitations

Not supportedWhy
DoctestsRun separately with cargo test --doc
#[bench]Use criterion instead
Some libtest flagsDifferent runner semantics

A common CI pattern is cargo nextest run && cargo test --doc.

nextest vs cargo test

Aspectcargo nextestcargo test
Process modelOne per testOne per binary
IsolationStrongShared within binary
Speed2–3x faster typicalBaseline
Flaky detectionBuilt-inNone
CI shardingBuilt-inManual
DoctestsNoYes

Resources