/commands/cargo/cargo-test-single-test
cargo test name: run a single test (or one module) in Rust
- tool
- Cargo
- versions
- Cargo 1.x
- os
- any
cargo test add runs only the tests whose full name contains add; every other test is counted as "filtered out". The filter matches the path of the test function, such as tests::adds_two, so a module name (cargo test tests::) selects all tests in that module. Add -- --exact to match one name exactly. Options after -- go to the test binary, options before it to Cargo.
Run one test
cargo new -q --lib --vcs none calc && cd calc
cat > src/lib.rs <<'EOF'
pub fn add(a: i32, b: i32) -> i32 { a + b }
pub fn sub(a: i32, b: i32) -> i32 { a - b }
#[cfg(test)]
mod tests {
use super::*;
#[test] fn adds_two() { assert_eq!(add(2, 2), 4); }
#[test] fn adds_negative() { assert_eq!(add(-1, 1), 0); }
#[test] fn subtracts() { assert_eq!(sub(5, 3), 2); }
}
EOF
cargo test -q --lib adds_two 2>&1 | sed -E 's/finished in [0-9.]+s/finished in Xs/'
echo "--- exact name"
cargo test -q --lib -- --exact tests::subtracts 2>&1 | sed -E 's/finished in [0-9.]+s/finished in Xs/'Output
running 1 test . test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in Xs --- exact name running 1 test . test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in Xs
The first run matched one test by substring, the second matched one test by its full path with --exact. --lib restricts the run to the library's unit tests; without it, Cargo also runs integration tests in tests/ and doc tests with the same filter.
Selecting tests
| Command | What it runs |
|---|---|
| cargo test add | Every test whose path contains add |
| cargo test tests:: | Every test in the tests module |
| cargo test -- --exact tests::subtracts | Exactly that test |
| cargo test --lib | Only unit tests in the library |
| cargo test --test api | Only the integration test file tests/api.rs |
| cargo test --doc | Only documentation tests |
| cargo test -p core add | Only in the workspace member core |
| cargo test -- --skip slow | Everything except tests whose name contains slow |
| cargo test -- --ignored | Only tests marked #[ignore]; --include-ignored runs both |
| cargo test -- --nocapture | Show println! output of passing tests |
| cargo test -- --test-threads=1 | Run tests one after another |
Pitfalls
- One filter only.
cargo test a bfails withunexpected argument 'b' found, because Cargo takes a single test name. Put several names after--(cargo test -- a b), where the test harness accepts more than one filter. - Options on the wrong side of
--.--nocapture,--exact,--ignoredand--test-threadsbelong after--;--lib,--test,--releaseand-pbefore it. - Filtering does not skip compilation. Every test target is still built. Use
--libor--test NAMEto build and run less. - Release-only bugs. Tests run in the debug profile;
cargo test --releaseuses the optimised build described in cargo build --release.
How to confirm it worked
The summary line, test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out, says how many tests ran and how many the filter excluded. If it reports 0 passed and every test filtered out, the name did not match: check it against cargo test -- --list, which prints every test name.
FAQ
How do I see println! output from a passing test?
Run cargo test -- --nocapture (or --show-output to print it after each passing test). By default the test harness captures standard output and only shows it for failing tests.
Why does cargo test run my filtered test twice or show doc tests?
Each test target (unit tests, each file in tests/, doc tests) is a separate binary, and the filter is passed to every one of them. Targets without a matching test report 0 tests and the filtered-out count. Use --lib, --test NAME or --doc to run only one target.
How do I run tests one at a time?
Pass -- --test-threads=1. Tests run in parallel threads by default, which breaks tests that share files, environment variables or a global state.