nextest is a test runner that can speed up Rust test execution by running tests in parallel and by intelligently skipping tests that are unlikely to fail.

Here’s nextest in action, running a small set of tests:

cargo nextest run

This command will discover and run all tests in your project. You’ll see output similar to this:

    Finished dev [unoptimized + debuginfo] target(s) in 0.05s
     Running 3 tests

   ✓ my_crate::tests::test_one
   ✓ my_crate::tests::test_two
   ✓ my_crate::tests::test_three

   3 / 3 passed in 0.12s

The Problem: Slow, Sequential Rust Tests

By default, cargo test runs tests one by one in a single thread. For projects with many tests, or tests that take a significant amount of time to set up or execute, this can lead to very long feedback loops. Imagine waiting 10 minutes for your tests to run every time you make a small change! This slowness discourages frequent testing and can lead to regressions slipping into production.

How nextest Solves It: Parallelism and Smart Skipping

nextest tackles this in a few key ways:

  1. Parallel Test Execution: The most significant speedup comes from running tests concurrently. nextest can spin up multiple test binaries and run tests from different binaries at the same time. It manages the complexity of this, ensuring that tests that depend on each other (which is rare in well-written tests) don’t interfere. You can control the number of parallel jobs with the jobs configuration option.

  2. Intelligent Test Selection (and Skipping): nextest keeps track of which tests have passed and failed in previous runs. If a test has consistently passed, nextest can skip running it altogether. This is especially useful for tests that are flaky or take a long time to execute but rarely fail. This feature is controlled by the repeat configuration option, which specifies how many times a test must pass before nextest starts skipping it.

  3. Improved Output and Diagnostics: nextest provides more detailed output than cargo test, including the ability to easily see the output of failed tests, even when running many tests in parallel. It also offers features like test filtering and coverage reporting.

Getting Started with nextest

First, install nextest as a development dependency:

cargo install cargo-nextest

Then, add a [nextest] section to your Cargo.toml to configure its behavior. Here’s a common starting point:

# Cargo.toml

[package]
name = "my_crate"
version = "0.1.0"
edition = "2021"

[dependencies]
# ...

[dev-dependencies]
# ...

[package.metadata.nextest]
# Run up to 8 tests in parallel. Adjust this based on your CPU cores and memory.
# A good starting point is your number of CPU cores.
jobs = 8

# After a test passes 3 times in a row, start skipping it.
# If a skipped test fails, it will be re-run.
repeat = 3

# If a test fails, rerun it once before marking it as failed.
# This helps identify flaky tests.
rerun-failed = 1

# Fail the entire test run if any test fails.
fail-fast = true

# Specify a different binary for tests if you have one
# runner = "my_test_runner"

With this configuration, you can run your tests using:

cargo nextest run

When you run this for the first time, all tests will execute. Subsequent runs will start skipping tests that have passed repeat = 3 times. If a skipped test does fail, nextest will automatically re-run it and mark it as failed if it still doesn’t pass. The rerun-failed = 1 option adds an extra layer of resilience by retrying a failing test once before declaring it a failure, helping to distinguish between genuinely broken tests and transient issues. The fail-fast = true setting ensures that as soon as any test fails, nextest stops the entire suite, giving you immediate feedback on the first problem.

The Mental Model: A Smarter Test Orchestrator

Think of nextest not just as a test runner, but as an intelligent orchestrator for your test suite. It doesn’t just blindly execute. It observes, learns, and adapts. The jobs setting is your primary lever for controlling raw throughput, directly mapping to how many tests can be actively processed simultaneously. The repeat setting is about optimizing your time, identifying tests that are already proven to be stable and allowing you to focus on the ones that are more likely to change or break. rerun-failed is a diagnostic tool, helping you pinpoint tests that are sometimes problematic. This combination allows you to drastically cut down on the time spent waiting for tests, especially in large projects where individual tests might be quick but the sheer volume is the bottleneck.

nextest builds a small, local cache of test results. This cache is typically stored in a .nextest directory in your project’s root. When nextest runs, it consults this cache to decide whether to run a test or skip it based on its repeat count. If a test’s output changes (e.g., you modify the test code or the code it tests), nextest will detect this and invalidate the cached result, ensuring that tests are re-run when their underlying logic might have changed.

The next thing you’ll likely want to explore is nextest’s powerful filtering capabilities, allowing you to run specific subsets of your tests based on names, features, or custom tags.

Want structured learning?

Take the full Cargo course →