Rust Test Assertions
Test assertions are the checks that compare a result with what it should be. assert_eq! checks that two values are equal.
Equal is not the only question
assert_ne! It requires two values to be different. Use it when the wrong result is clear but the exact result is not. assert! checks any condition you can write:
assert_ne!(greeting("Carol"), "");
assert!(greeting("Carol").contains("Carol"));A failed check shows both values
When assert_eq! or assert_ne! fails, the report prints the two values as left and right, so you can see what went wrong:
assert_eq!(greeting("Carol"), "Hello, Ana!");Say what the check meant
Extra arguments after the condition work like format! arguments. They appear in the failure report and explain what the check meant:
let r = greeting("Carol");
assert!(r.contains("Carol"), "greeting was `{r}`");Your own types can join in
The compared values must implement PartialEq and Debug. For your own structs and enums, derive both:
#[derive(PartialEq, Debug)]
struct Score {
points: i32,
}Pin the panic to its reason
Plain #[should_panic] passes on any panic at all — even one for the wrong reason. expected also requires the panic message to contain your text:
#[test]
#[should_panic(expected = "between 1 and 100")]
fn guess_too_big() {
check_guess(200);
}Compare decimals with a gap
Decimal fractions are stored as binary guesses. 0.1 + 0.2 does not equal 0.3 exactly. assert_eq! would fail a correct programme:
#[test]
fn prices_add_up() {
let total: f64 = 0.1 + 0.2;
assert!((total - 0.3).abs() < 1e-9);
}Example
fn greeting(name: &str) -> String { format!("Hello, {name}!") }
fn check_guess(value: i32) { if value < 1 || value > 100 { panic!("Guess must be between 1 and 100, got {value}."); } }
#[cfg(test)]
mod tests {
use super::*;
#[test] fn greeting_has_name() { let r = greeting("Carol"); assert!(r.contains("Carol"), "greeting was `{r}`"); }
#[test] fn greeting_is_not_empty() { assert_ne!(greeting("Carol"), ""); }
#[test] #[should_panic(expected = "between 1 and 100")] fn guess_too_big() { check_guess(200); }
}
fn main() { check_guess(42); println!("{} / guess 42 is fine", greeting("Carol")); }Key points
- Use a gap check for f32 and f64 results.
- Exact equality asks the wrong question of a binary fraction.
- Prefer assert_eq! or assert_ne! when two values are involved — the printed pair is the clue you will want later.
- An assertion passes when the result matches the expected value and fails when it does not.
In this example, three tests check one small program in three sharper ways. greeting_has_name uses assert! with a custom message: if the greeting ever lost the name, the failure would print the greeting it actually got. greeting_is_not_empty uses assert_ne! to require the greeting to differ from an empty string. guess_too_big uses should_panic with expected. check_guess(200) must panic. The panic message must contain "between 1 and 100". A panic for any other reason would fail this test. main itself calls check_guess(42), which is inside the range, so nothing panics and the greeting prints.
Note
assert! only reports that a check was false.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
What does #[should_panic(expected = "too big")] add to a panic test?