Rust Tutorial · Projects and Testing · Lesson 28 of 29

Rust Testing

Write unit tests with #[test] and assertions, test errors and panics, and run them with cargo test.

Create a free account to save this page, take notes and track your progress. Sign in

Unit tests

Tests live next to the code in a #[cfg(test)] module and use assert!, assert_eq! and assert_ne!. cargo test compiles and runs them; a failing assertion shows the expected and actual values, as in the third test below, which exposes a rounding decision the code didn't make deliberately.

Unit tests, including one that fails
pub fn apply_discount(price_cents: u64, percent: u8) -> Result<u64, String> {
    if percent > 100 {
        return Err(format!("invalid discount {percent}%"));
    }
    Ok(price_cents - price_cents * percent as u64 / 100)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn ten_percent_off() {
        assert_eq!(apply_discount(2_000, 10), Ok(1_800));
    }

    #[test]
    fn rejects_more_than_100_percent() {
        assert!(apply_discount(2_000, 150).is_err());
    }

    #[test]
    fn half_price_rounds_down() {
        // fails: the integer maths rounds 499.5 cents of discount down, so the price is 500, not 499
        assert_eq!(apply_discount(999, 50), Ok(499), "half of 9.99 should round in the customer's favour");
    }
}

Output

running 3 tests
test tests::half_price_rounds_down ... FAILED
test tests::rejects_more_than_100_percent ... ok
test tests::ten_percent_off ... ok

failures:

---- tests::half_price_rounds_down stdout ----

thread 'tests::half_price_rounds_down' panicked at main.rs:25:9:
assertion `left == right` failed: half of 9.99 should round in the customer's favour
  left: Ok(500)
 right: Ok(499)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    tests::half_price_rounds_down

test result: FAILED. 2 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in <time>

Run this on your computer — see “Get Started” for setup.

Integration tests go in a tests/ directory and use your crate like an external user; documentation examples in /// comments are run as tests too.

Test yourself

Which attribute marks a function as a test?

  1. #[unit]
  2. #[test]
  3. #[cfg(test)]
  4. @Test
Show answer

Answer: #[test]

#[cfg(test)] only compiles the module in test builds; #[test] marks each test.

Was this page helpful?