Unit Testing
#[test]
The #[test] attribute marks a zero-argument Rust function as a test case to be registered and executed by the rustc --test harness. Functions marked with #[test] are omitted from normal cargo build and cargo run compilations and are only compiled when building in test mode (cargo test).
#[test]
fn my_test_case() -> () or Result<(), E>
|
+-- Compiled under `cargo build`? NO (stripped by compiler)
+-- Compiled under `cargo test`? YES (registered in libtest runner)
Supported Function Signatures for #[test]
A function annotated with #[test] must take zero parameters (fn()) and have one of two return types:
- Unit
()(default): Passes if the function finishes without panicking; fails if a panic occurs. Result<(), E>whereE: std::fmt::Debug(anyTerminationtype): Passes onOk(())and fails onErr(e)(printing"Error: {e:?}"), allowing ergonomic use of the?operator inside tests without.unwrap().
use std::num::ParseIntError;
fn parse_pair(input: &str) -> Result<(i32, i32), ParseIntError> {
let (left, right) = input.split_once(',').unwrap_or((input, "0"));
Ok((left.trim().parse()?, right.trim().parse()?))
}
#[test]
fn test_with_assertions() {
assert_eq!(parse_pair("10, 20"), Ok((10, 20)));
}
#[test]
fn test_with_question_mark() -> Result<(), ParseIntError> {
let (x, y) = parse_pair("30, 40")?;
assert_eq!(x + y, 70);
Ok(())
}
fn main() {
println!("Parsed pair: {:?}", parse_pair("10, 20").unwrap());
}
Parsed pair: (10, 20)
Running cargo test executes both test functions:
running 2 tests
test test_with_assertions ... ok
test test_with_question_mark ... ok
test result: ok. 2 passed; 0 failed; 0 filtered out; finished in 0.00s
Compile-Time Restrictions on #[test] Functions
A #[test] function cannot accept parameters or generic type arguments because the test runner invokes it directly without arguments:
// ❌ does not compile
#[test]
fn invalid_parameterized_test(input: i32) {
assert!(input > 0);
}
error: functions used as tests can not have any arguments
--> src/lib.rs:2:1
|
2 | #[test]
| ------- in this attribute macro expansion
3 | fn invalid_parameterized_test(input: i32) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Note that #[test] and #[should_panic] cannot be combined with a Result<(), E> return type—#[should_panic] tests must return ().