Following up on Q/A: How to run a specific unit test in Rust?
When using the described solution cargo test path::to::some_test -- --exact
in a project that mixes a library with binaries, how to suppress all the "0 passed" noise in the output?
To demonstrate the problem: I've create a minimal test project via cargo new test-project --lib
. Then I've created the following files:
.
├── Cargo.toml
└── src
├── bin
│ ├── bar.rs
│ ├── baz.rs
│ └── foo.rs
└── lib.rs
The lib.rs
contains:
#[cfg(test)]
mod tests {
#[test]
fn test_foo() {
assert!(true);
}
#[test]
fn test_bar() {
assert!(true);
}
}
All three binaries are just fn main() {}
dummies.
When running cargo test tests::test_foo -- --exact
I can see that filtering the unit tests to the specific test_foo
works, but the output gets littered with "running 0 tests" from the binaries:
Finished test [unoptimized + debuginfo] target(s) in 0.00s
Running unittests src/lib.rs (target/debug/deps/test_project-72d9bd396ce43ab9)
running 1 test
test tests::test_foo ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s
Running unittests src/bin/bar.rs (target/debug/deps/bar-1d7d5b4c3ec748b3)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/bin/baz.rs (target/debug/deps/baz-ebd229498f923881)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Running unittests src/bin/foo.rs (target/debug/deps/foo-f88dc03912c7d051)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
My real life project is a cargo workspace project with many workspace members, each containing various utility binaries. As a result of the behavior demonstrated above, running specific tests isn't very usable: Depending on the filter the matching results gets sandwiched by ~3 screen pages of "running 0 tests", and I when I misspell a test filter, and I get ~3 pages of actual 0 tests matched (which happily passes of course!) -- which is hard to tell apart.
Is there a way to suppress the output from non-matching modules altogether?
To reduce noise when filtering tests, pass a Cargo target selection option (and package selection if you are in a workspace), so you're only running the target that has the test you want, not all the targets. In this case, you would use --lib
.
cargo test --lib -- --exact path::to::some_test
(It's not currently possible for Cargo to do this for you, because Cargo has no idea what tests each target contains — tests are found by running the binary (which is what the output is announcing) and there is no specific communication protocol between Cargo and the binaries other than exit code.)
To reduce noise in general, and save some build time too, you can disable testing for targets that don't have any tests. For each such target add test = false
to the Cargo.toml
:
[[bin]]
name = "foo"
test = false
[[bin]]
name = "bar"
test = false
[[bin]]
name = "baz"
test = false
Of course, this comes with a risk of forgetting you wrote this config, and thus writing tests that don't get run.