← All articles
a computer desk with two monitors and a laptop

cargo-nextest: Faster Rust Testing with Better Output

Rust 2026-03-04 · 4 min read rust testing nextest cargo ci developer tools test runner
By DevTools Guide Editorial TeamSoftware engineers and developer advocates covering tools, workflows, and productivity for modern development teams.

cargo test is built into Rust's toolchain and works well for simple cases. But as your project grows — more tests, slower builds, flaky network tests, CI that needs structured output — cargo test's limitations become friction. cargo-nextest is a replacement that runs tests faster, presents output more clearly, and integrates better with CI systems.

Photo by Boitumelo on Unsplash

Why nextest

The headline number: nextest typically runs Rust test suites 2–3× faster than cargo test. This happens because nextest runs each test as its own process, enabling true parallelism. cargo test uses threads within a single process, which limits parallelism when tests share global state or block on I/O.

Other improvements:

Installation

# Via cargo-binstall (fastest — downloads precompiled binary)
cargo binstall cargo-nextest

# Or via cargo install
cargo install cargo-nextest --locked

# Or download binary directly
curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ~/.cargo/bin

Verify:

cargo nextest --version

Basic Usage

# Run all tests (replaces cargo test)
cargo nextest run

# Run tests matching a filter
cargo nextest run auth

# Run tests in a specific package
cargo nextest run -p my-crate

# List tests without running
cargo nextest list

# Run with increased parallelism
cargo nextest run --test-threads 16

The output looks different from cargo test:

    Finished test [unoptimized + debuginfo] target(s) in 2.34s
    Starting 47 tests across 3 test binaries

────────────── TESTS SKIPPED: 0 ──────────────────────────
────────────── TESTS PASSED: 47 ─────────────────────────

    Test run complete. 47 passed, 0 skipped, 0 failed in 1.823s

Each test result shows the test name, duration, and outcome. Failures include captured output.

Like what you're reading? Subscribe to DevTools Guide — free weekly guides in your inbox.

Configuration

Configure nextest in .cargo/nextest.toml (or in Cargo.toml under [profile.nextest]):

[profile.default]
# Fail fast after N test failures
fail-fast = false

# Retry flaky tests up to 2 times
retries = 2

# Slow test threshold (print warning)
slow-timeout = { period = "30s", terminate-after = 3 }

# Maximum parallel threads
test-threads = "num-cpus"

[profile.ci]
# CI profile: JUnit output, no progress bar
retries = 2
failure-output = "final"
status-level = "all"
final-status-level = "all"

Run with a specific profile:

cargo nextest run --profile ci

Per-Test Configuration

Some tests need special handling — integration tests that hit a real database, tests that must run serially, tests known to be slow:

# .cargo/nextest.toml

[[profile.default.overrides]]
# Tests tagged as requiring serial execution
filter = 'test(#[serial])'
test-threads = 1

[[profile.default.overrides]]
# Database integration tests get more retries
filter = 'test(/integration/) and test(/database/)'
retries = 5

[[profile.default.overrides]]
# Known slow test — don't fail on slow threshold
filter = 'test(test_large_data_processing)'
slow-timeout = { period = "5m" }

The filter syntax supports test names, binary names, tags, and boolean operators.

CI Integration

GitHub Actions

name: Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable

      - uses: taiki-e/install-action@cargo-nextest

      - name: Run tests
        run: cargo nextest run --profile ci

      - name: Upload JUnit results
        uses: mikepenz/action-junit-report@v4
        if: always()
        with:
          report_paths: 'target/nextest/ci/junit.xml'

Test Partitioning for Parallel CI

Split your test suite across multiple machines to run in parallel:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        partition: [1, 2, 3, 4]
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - uses: taiki-e/install-action@cargo-nextest

      - name: Run tests (partition ${{ matrix.partition }}/4)
        run: |
          cargo nextest run \
            --partition count:${{ matrix.partition }}/4 \
            --profile ci

Four machines run in parallel, each handling a quarter of the tests.

Filtering Syntax

nextest's filter syntax is powerful:

# Run tests with "auth" in the name
cargo nextest run auth

# Run tests in a specific binary
cargo nextest run --test integration_tests

# Exclude slow tests
cargo nextest run 'not test(slow)'

# Combine filters
cargo nextest run 'test(auth) and not test(network)'

# Run only doc tests (note: nextest doesn't run doc tests — use cargo test for those)

Known Limitations

nextest does not run doc tests (cargo test --doc). For projects that rely heavily on doctests for documentation examples, you'll need to run both:

cargo nextest run        # Unit and integration tests
cargo test --doc         # Doc tests only

This is tracked as a known limitation on the nextest GitHub. For most projects, running both in CI is straightforward.

nextest vs cargo test

Feature nextest cargo test
Speed 2–3× faster Baseline
Output format Structured table Flat text
Test isolation Per-process Per-thread
Flaky test retries
JUnit XML
CI partitioning
Doc tests
Standard toolchain No (install required) Yes

For most Rust projects, nextest is worth adopting — the speed improvement alone justifies it, and better CI integration is a bonus. The only reason to stick with cargo test exclusively is if you depend heavily on doctests or can't add a binary dependency to your build.

Get free weekly tips in your inbox. Subscribe to DevTools Guide