Testing in Rust
| #[test] functions | |
| assert! macros | |
| cargo test | |
| Tests beside code |
#[test] functions
A test is a plain function with the test attribute above it. The harness runs each marked function and reports pass or fail per name.
Keep tests small and focused: one behavior per function with a name that states the expected outcome.
fn add(a: i32, b: i32) -> i32 {
a + b
}
#[test]
fn adds_two() {
assert!(add(1, 1) == 2);
}
The add function holds the logic and adds_two checks one case. The attribute is the only marker the harness needs.
assert! macros
Assert macros state what must hold and stop the test with details on mismatch. Use assert for booleans and the equal variants when two values must match.
Clear expected values in the call make failures readable without opening extra logs.
#[test]
fn checks() {
assert!(1 + 1 == 2);
assert_eq!(2 + 2, 4);
}
The first line checks a condition and the second compares two values. Assert_eq prints both sides when they differ, which speeds up diagnosis.
cargo test
Run cargo test in the project root. Passing tests print ok lines and a summary count at the end.
Filter by name to run one test during debugging, and run the full suite before every commit.
cargo test
test adds_two ... ok
One line per test shows its name and result. A green summary confirms the whole suite stayed healthy.
Tests beside code
Unit tests live in a tests module at the bottom of the same file. The cfg test gate compiles the module for test runs only, so release builds skip it fully.
Import the parent items with a use super path and cover each public function near its definition.
fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::add;
#[test]
fn adds_two() {
assert_eq!(add(1, 1), 2);
}
}
Logic and checks share one file but build separately. New readers find the contract of add right below its body.
Next: Error handling
Article author: Arthur Isaev