/flags/cargo/cargo-test-nocapture
cargo test -- --nocapture: show println! output of passing tests
- tool
- Cargo
- command
- cargo test
- flag
- -- --nocapture, -- --show-output
- default
- output of passing tests is captured and hidden
By default the Rust test harness captures everything a test prints with println! or eprintln! and shows it only when that test fails. cargo test -- --nocapture turns capturing off, so the output of passing tests appears in the terminal as it happens. The flag belongs to the test binary, which is why it goes after the -- separator; --show-output is the alternative that keeps capturing but prints the output after each successful test.
Default, --nocapture and --show-output
cargo new -q --vcs none app && cd app
cat > src/main.rs <<'EOF'
fn main() {}
#[test]
fn prints_something() {
println!("hello from the test");
assert_eq!(2 + 2, 4);
}
EOF
cargo build -q --tests 2>/dev/null
echo "--- cargo test"
cargo test -q 2>/dev/null | sed -E 's/finished in [0-9.]+s/finished in Xs/'
echo "--- cargo test -- --nocapture"
cargo test -q -- --nocapture 2>/dev/null | sed -E 's/finished in [0-9.]+s/finished in Xs/'
echo "--- cargo test -- --show-output"
cargo test -q -- --show-output 2>/dev/null | sed -E 's/finished in [0-9.]+s/finished in Xs/'
echo "--- wrong side of --"
cargo test -q --nocapture 2>&1 | head -1Output
--- cargo test
running 1 test
.
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in Xs
--- cargo test -- --nocapture
running 1 test
hello from the test
.
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in Xs
--- cargo test -- --show-output
running 1 test
.
successes:
---- prints_something stdout ----
hello from the test
successes:
prints_something
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in Xs
--- wrong side of --
error: unexpected argument '--nocapture' found-q makes the progress compact (one dot per test) and sed removes the run time. With --nocapture the line appears in the middle of the run; with --show-output it is listed under successes: at the end. Before the --, Cargo itself rejects the option.
Related harness options
| Option (after --) | Effect |
|---|---|
| --nocapture | Print test output live, do not capture |
| --show-output | Capture, then print the output of passing tests after the run |
| --test-threads=1 | Run tests one at a time; keeps --nocapture output in order |
| --exact NAME | Run only the test with exactly this name |
| --ignored / --include-ignored | Run only, or also, tests marked #[ignore] |
| RUST_TEST_NOCAPTURE=1 (env) | Same as --nocapture |
| RUST_TEST_THREADS=1 (env) | Same as --test-threads=1 |
Selecting single tests by name is covered in run a single test with cargo.
Readable output with parallel tests
Tests run in parallel threads, so with --nocapture the lines of different tests can interleave. Combine both options when you debug a group of tests:
cargo test parser -- --nocapture --test-threads=1Pitfalls
- Output written by spawned child processes or directly to the file descriptor (
std::io::stdout().write_allon a raw handle, C libraries) is not captured by the harness at all, with or without the flag. dbg!andeprintln!write to stderr; they are captured the same way asprintln!.- Integration tests in
tests/and doc tests accept the same options:cargo test --doc -- --nocapture. - Options before
--belong to Cargo (--release,-p crate,--lib,--test name); the same split applies to cargo run -- args.
FAQ
Why does cargo test --nocapture say unexpected argument?
--nocapture is an option of the test binary, not of Cargo. It must come after the double dash: cargo test -- --nocapture. Everything before -- is parsed by Cargo, everything after it by the test harness.
What is the difference between --nocapture and --show-output?
--nocapture prints output live while tests run, so lines of parallel tests can interleave. --show-output keeps capturing and prints each passing test's output in a block after the run, which is easier to read.
Can I turn off capturing without the flag?
Yes, set the environment variable RUST_TEST_NOCAPTURE=1. It has the same effect as -- --nocapture and is handy in IDE run configurations or CI.