If you find this helpful, please like, bookmark, and follow. To keep learning along, follow this series.
11.6.1 Controlling How Tests Run
Like cargo run, cargo test compiles the code and produces a binary used for testing, except that cargo test runs in test mode.
You can change cargo testβs behavior by passing arguments. If you pass no arguments, the default behavior is:
- Run all tests in parallel
- Capture all output when tests pass, so it is easier to read test-related output. If a test fails, the output is shown so the programmer can debug.
Command-line arguments come in two categories:
- Arguments for
cargo testitself, placed immediately aftercargo test - Arguments for the generated executable, placed after
--. For example,cargo test -- --helpshows all arguments available after--, that is, all arguments for the executable.
11.6.2 Running Tests in Parallel
When running multiple tests, Rust uses multiple threads by default so tests run in parallel. This is faster, but the tests must not depend on one another, and they must not depend on shared state such as the environment, working directory, or environment variables.
If two tests depend on shared state, and one test changes that state before the other finishes, the other tests that share the same state will be affected.
If you do not want tests to run in parallel, or if you want to control exactly how many threads are used, you can use the --test-threads argument, which is passed to the binary. Put the thread count right after this argument.
For example, cargo test -- --test-threads=1 uses one thread, which means multiple tests take longer than they would in parallel. But it has an advantage: because the tests run sequentially, they are less likely to interfere with one another through shared state.
11.6.3 Showing Function Output
By default, if a test passes, Rustβs test library captures output written to standard output, such as println! output. If a test fails, the printed output is shown together with the failure message.
For example:
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);
}
}
- The function under test,
prints_and_returns_10, prints the value it receives and then returns 10. - The
this_test_will_passtest passes 4 to the function, so the function prints 4 and then compares the fixed return value with 10. This test succeeds. - The
this_test_will_failtest passes 8 to the function, so the function prints 8 and then compares the fixed return value with 5. This test fails.
Test result:
$ cargo test
Compiling silly-function v0.1.0 (file:///projects/silly-function)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.58s
Running unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166)
running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... ok
failures:
---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9:
assertion `left == right` failed
left: 10
right: 5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::this_test_will_fail
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass `--lib`
The success case does not appear in the test output, but the failure case does: I got the value 8.
If you want successful tests to print their output too, add the flag cargo test -- --show-output. The output then looks like this:
$ cargo test -- --show-output
Compiling silly-function v0.1.0 (file:///projects/silly-function)
Finished `test` profile [unoptimized + debuginfo] target(s) in 0.60s
Running unittests src/lib.rs (target/debug/deps/silly_function-160869f38cff9166)
running 2 tests
test tests::this_test_will_fail ... FAILED
test tests::this_test_will_pass ... ok
successes:
---- tests::this_test_will_pass stdout ----
I got the value 4
successes:
tests::this_test_will_pass
failures:
---- tests::this_test_will_fail stdout ----
I got the value 8
thread 'tests::this_test_will_fail' panicked at src/lib.rs:19:9:
assertion `left == right` failed
left: 10
right: 5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
tests::this_test_will_fail
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
error: test failed, to rerun pass `--lib`
Top comments (0)