| name | nextest |
| description | Use when running Rust tests with cargo-nextest. Keywords: cargo nextest, nextest, test runner, run tests, test parallelism, test threads, flaky test, retry, slow test, timeout, test group, filterset, test partition, sharding, continuous integration (CI) testing, nextest profile, nextest config, .config/nextest.toml, cargo nextest run, cargo nextest list, test archive, JUnit, stress test, miri, test coverage, cargo-mutants, criterion, debugger, tracer |
| globs | ["**/Cargo.toml","**/.config/nextest.toml"] |
| user-invocable | false |
cargo-nextest: The Rust Test Runner
cargo-nextest runs each test in its own process, in parallel. It builds test
binaries, queries them for tests, then executes each test individually. This
eliminates bottlenecks from long-pole tests and provides structured per-test
results. Custom test harnesses may need adaptation for this model.
Quick Reference
Running Tests
cargo nextest run
cargo nextest run test_name
cargo nextest run -p my-crate
cargo nextest run --workspace
cargo nextest run -j 4
cargo nextest run -j 1
cargo nextest run --no-fail-fast
cargo nextest run --retries 2
cargo nextest run --no-capture
cargo nextest run -P ci
Listing and Selecting Tests
cargo nextest list
cargo nextest list -T json-pretty
cargo nextest run -E 'package(my-crate)'
cargo nextest run -E 'test(/regex/)'
cargo nextest run -E 'deps(my-crate)'
cargo nextest run -- --skip slow --exact test_foo
CI Essentials
cargo nextest run -P ci --no-fail-fast
cargo nextest run --partition slice:1/3
cargo nextest archive --archive-file a.tar.zst
cargo nextest run --archive-file a.tar.zst
Parallelism and Thread Control
By default, nextest runs num-cpus tests concurrently. Control this with:
- CLI:
-j N or --test-threads N (also num-cpus)
- Env:
NEXTEST_TEST_THREADS=N
- Config:
test-threads = N or test-threads = "num-cpus"
Negative values are relative to CPU count (e.g., -2 means num_cpus - 2).
Heavy tests (threads-required)
Mark resource-intensive tests to consume multiple thread slots:
[[profile.default.overrides]]
filter = 'test(/^tests::heavy::/)'
threads-required = 2
Test groups (mutual exclusion / rate-limiting)
Logical semaphores/mutexes for subsets of tests:
[test-groups]
serial-db = { max-threads = 1 }
rate-limited = { max-threads = 4 }
[[profile.default.overrides]]
filter = 'package(db-tests)'
test-group = 'serial-db'
[[profile.default.overrides]]
filter = 'test(api_)'
test-group = 'rate-limited'
Inspect with cargo nextest show-config test-groups.
Configuration
Config file: .config/nextest.toml in the workspace root.
Profiles
Profiles provide named sets of options. Select with -P <name> or
NEXTEST_PROFILE=<name>.
[profile.ci]
fail-fast = false
retries = 2
For complete profile examples (including profile.default and
profile.ci.junit for JUnit output), see ref/ci-patterns.md.
Profiles inherit from default unless inherits is specified.
Hierarchical resolution
- CLI arguments
- Environment variables
- Per-test overrides (in profile, then default)
- Profile configuration
- Default configuration
Per-test overrides
[[profile.default.overrides]]
filter = 'test(test_e2e)'
retries = 3
slow-timeout = { period = "120s", terminate-after = 5 }
threads-required = 2
Overrides support: retries, slow-timeout, leak-timeout,
threads-required, test-group, success-output, failure-output,
priority, run-extra-args, default-filter.
Retries and Flaky Tests
retries = 3
retries = { backoff = "fixed", count = 3, delay = "1s" }
retries = { backoff = "exponential", count = 4, delay = "2s", max-delay = "10s", jitter = true }
CLI --retries N and env NEXTEST_RETRIES=N override all config including
per-test overrides, and disable backoff delays.
A test that fails then succeeds on retry is marked flaky (ultimately
passes, exit code 0).
Timeouts
Slow test warnings
slow-timeout = "60s"
Terminating hung tests
slow-timeout = { period = "30s", terminate-after = 4 }
slow-timeout = { period = "30s", terminate-after = 4, grace-period = "5s" }
Global timeout
global-timeout = "2h"
Timeout as success (fuzz tests)
[[profile.default.overrides]]
filter = 'package(fuzz-targets)'
slow-timeout = { period = "30s", terminate-after = 1, on-timeout = "pass" }
Filtersets (Domain-specific language, DSL)
Specified with -E / --filterset. Core concepts:
- Predicates:
test(...), package(...), deps(...), rdeps(...),
kind(...), platform(...), default()
- Matchers: exact (
=), contains (~), regex (/../), glob (#)
- Operators:
not/!, and/&/-, or/|/+ with () grouping
- CLI filtersets intersect with
default-filter unless
--ignore-default-filter is set
See ref/filterset-dsl.md for the complete predicate table, matcher rules,
operator precedence, escape sequences, and advanced examples.
Environment-Aware Configuration
Per-platform overrides
[[profile.default.overrides]]
platform = 'cfg(target_os = "linux")'
slow-timeout = "120s"
[[profile.default.overrides]]
platform = { host = "cfg(unix)", target = "aarch64-apple-darwin" }
threads-required = 2
Agent sandbox considerations
When running inside an agent sandbox (constrained CPU/memory):
- Use
-j 2 or -j 4 to limit parallelism
- Set generous timeouts:
slow-timeout = { period = "120s", terminate-after = 3 }
- Consider
--no-fail-fast to gather all failures in one run
- Use
--show-progress=counter for non-interactive output
- Set
NEXTEST_NO_INPUT_HANDLER=1 to disable terminal key handling
Continuous integration (CI) workflow overview
For production-ready profile config, sharding strategies, build/run split
archives, and full GitHub/GitLab examples, see ref/ci-patterns.md.
cargo nextest run -P ci
cargo nextest run -P ci --partition slice:1/3
cargo nextest archive --workspace --archive-file tests.tar.zst
cargo nextest run --archive-file tests.tar.zst --partition slice:1/3
Archiving and Reusing Builds
Build once and run on multiple machines (same platform and source revision):
cargo nextest archive --archive-file tests.tar.zst
cargo nextest run --archive-file tests.tar.zst
Use --workspace-remap <path> when the checkout path differs on the target
machine.
See ref/ci-patterns.md for full archive patterns, include/exclude options,
and CI artifact workflows.
Stress Testing
cargo nextest run --stress-count 10 test_flaky
cargo nextest run --stress-count infinite test_x
cargo nextest run --stress-duration 5m test_x
Record, Replay, and Rerun (Experimental)
Enable in ~/.config/nextest/config.toml:
[experimental]
record = true
[record]
enabled = true
Then:
cargo nextest run
cargo nextest run -R latest
cargo nextest replay
cargo nextest store list
cargo nextest store export latest
Test Priorities
[[profile.default.overrides]]
filter = 'test(smoke_)'
priority = 50
[[profile.default.overrides]]
filter = 'test(slow_e2e_)'
priority = -50
Reporter and Output Control
| Option | Values | Default |
|---|
--failure-output | immediate, final, immediate-final, never | immediate |
--success-output | immediate, final, immediate-final, never | never |
--status-level | none, fail, retry, slow, leak, pass, skip, all | pass |
--final-status-level | none, fail, flaky, slow, skip, pass, all | flaky |
--show-progress | auto, none, bar, counter, only | auto |
Press t during a run to dump status of currently-running tests (interactive
terminals only). On macOS, Ctrl-T also works. On any Unix, send SIGUSR1.
Setup Scripts (Experimental)
Pre-test scripts that can set environment variables for tests:
experimental = ["setup-scripts"]
[scripts.setup.db-seed]
command = 'cargo run -p seed-db'
slow-timeout = { period = "60s", terminate-after = 2 }
[[profile.default.scripts]]
filter = 'rdeps(db-tests)'
setup = 'db-seed'
Scripts write env vars to $NEXTEST_ENV:
echo "DATABASE_URL=postgres://localhost/test" >> "$NEXTEST_ENV"
Key Environment Variables
Nextest reads
| Variable | Purpose |
|---|
NEXTEST_TEST_THREADS | Override test thread count |
NEXTEST_RETRIES | Override retry count |
NEXTEST_PROFILE | Select profile |
NEXTEST_FAILURE_OUTPUT | Override failure output mode |
NEXTEST_VERBOSE | Verbose output |
Nextest sets (at test runtime)
| Variable | Value |
|---|
NEXTEST | Always "1" |
NEXTEST_RUN_ID | UUID for the run |
NEXTEST_EXECUTION_MODE | "process-per-test" |
NEXTEST_ATTEMPT | 1-indexed attempt number |
NEXTEST_TEST_GROUP | Group name or "@global" |
NEXTEST_BIN_EXE_<name> | Path to binary target (integration tests) |
NEXTEST_BINARY_ID | Binary ID of the current test |
NEXTEST_ATTEMPT_ID | Globally unique attempt identifier |
NEXTEST_TEST_GLOBAL_SLOT | Global slot number (0-indexed, unique among running tests) |
NEXTEST_TEST_GROUP_SLOT | Group slot number ("none" if not in a group) |
Slot numbers are useful for assigning resources like port numbers to tests.
They are unique for the lifetime of the test, stable across retries, and
compact (each test gets the smallest available slot).
Environment safety
Because nextest runs each test in its own process, calling std::env::set_var
at the beginning of a test is safe in practice (before spawning threads).
Debugger and Tracer Support
cargo nextest run --debugger "rust-gdb --args" test_name
cargo nextest run --debugger "rust-lldb --" test_name
cargo nextest run --tracer strace test_name
cargo nextest run --tracer "strace -f" test_name
Both modes disable timeouts and output capture, and require exactly one test
to be selected. Key differences:
--debugger: Passes stdin through, disables signal handling and process
groups (interactive debugging with gdb, lldb, WinDbg, CodeLLDB)
--tracer: Null stdin, standard signal handling, process groups for
isolation (non-interactive tracing with strace, dtruss, truss)
Integrations
Miri (undefined behaviour detection)
cargo miri nextest run
cargo miri nextest run --target mips64-unknown-linux-gnuabi64
Nextest auto-selects the default-miri profile under Miri. Configure it in
.config/nextest.toml:
[profile.default-miri]
slow-timeout = { period = "60s", terminate-after = 2 }
Miri tests run in parallel with nextest (Miri itself is single-threaded, so
cargo miri test is limited to serial execution). Archiving is not supported
under Miri.
Test coverage
cargo llvm-cov nextest
Merge with doctests (nextest doesn't run doctests):
cargo llvm-cov --no-report nextest
cargo llvm-cov --no-report --doc
cargo llvm-cov report --doctests --lcov --output-path lcov.info
Mutation testing (cargo-mutants)
cargo mutants --test-tool=nextest
Or set permanently in .cargo/mutants.toml:
test_tool = "nextest"
Criterion benchmarks in test mode
By default, cargo nextest run excludes benchmarks. To verify benchmarks
compile and don't panic (single iteration, no measurement):
cargo nextest run --all-targets
cargo nextest run --benches
Requires Criterion 0.5.0+. For actual performance measurement, use the
experimental cargo nextest bench (requires experimental = ["benchmarks"]).
Reference
For detailed reference on specific topics, see the ref/ directory in this
skill:
ref/config-reference.md — Full configuration parameter reference
ref/filterset-dsl.md — Complete filterset DSL reference
ref/ci-patterns.md — CI/CD patterns for archiving, sharding, and GitHub Actions