Controlling How Tests Are Run

cargo test compiles and runs tests with customizable behavior through command-line options. Options for cargo test come before --, while options for the test binary come after --.

Parallel vs Sequential Execution

Tests run in parallel by default using threads. To run sequentially or control thread count:

$ cargo test -- --test-threads=1

Showing Function Output

By default, passing tests capture output (e.g., println!). Failed tests show captured output. To see output from passing tests:

$ cargo test -- --show-output

Example test with output:

fn prints_and_returns_10(a: i32) -> i32 {
    println!("I got the value {a}");
    10
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn this_test_will_pass() {
        let value = prints_and_returns_10(4);
        assert_eq!(value, 10);
    }

    #[test]
    fn this_test_will_fail() {
        let value = prints_and_returns_10(8);
        assert_eq!(value, 5);
    }
}

Running Subset of Tests

Single Tests

Run specific test by name:

$ cargo test one_hundred

Filtering Tests

Run multiple tests matching a pattern:

$ cargo test add  // Runs tests with "add" in the name

Module names are part of test names, so you can filter by module.

Ignoring Tests

Mark expensive tests to skip during normal runs:

pub fn add(left: u64, right: u64) -> u64 {
    left + right
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }

    #[test]
    #[ignore]
    fn expensive_test() {
        // code that takes an hour to run
    }
}

Run only ignored tests:

$ cargo test -- --ignored

Run all tests (including ignored):

$ cargo test -- --include-ignored