🎓 A1Learner
🔍

Rust Testing Basics

A test is a small function that checks other code by itself. The cargo test command runs every test and reports which ones passed.

Checking by eye

Printing answers leaves the checking to a person. After every change, someone must read the output and judge it:

fn add(a: i32, b: i32) -> i32 {
    a + b
}

fn main() {
    println!("add(2, 3) = {}", add(2, 3));
    println!("add(-1, 1) = {}", add(-1, 1));
}

A test checks by itself

The #[test] attribute makes a plain function into a test. This one checks add on its own:

fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[test]
fn it_adds() {
    assert_eq!(add(2, 3), 5);
}

cargo test prints a report

Save add with two tests in a file and run cargo test. The report names each test and gives its verdict. The last line counts the passes:

// in your terminal:
// $ cargo test
// running 2 tests
// test it_adds ... ok
// test it_handles_negatives ... ok
//
// test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

A test that must panic

Some code should fail. #[should_panic] turns a test around, so it passes only when the code inside panics:

#[test]
#[should_panic]
fn third_score_missing() {
    let scores = vec![10, 20];
    let _third = scores[5];
}

Example

fn grade(score: i32) -> &'static str {
    if score >= 50 {
        "pass"
    } else {
        "fail"
    }
}

fn main() {
    println!("82 is a {}", grade(82));
    println!("run cargo test to check grade");
}

#[test]
fn high_score_passes() {
    assert_eq!(grade(82), "pass");
}

#[test]
fn low_score_fails() {
    assert_eq!(grade(30), "fail");
}

#[test]
#[should_panic]
fn third_score_missing() {
    let scores = vec![10, 20];
    let _third = scores[5];
}

Key points

  • A test is an ordinary function with #[test] written above it.
  • assert_eq! checks that two values are equal.
  • assert_eq! panics when the two values differ.
  • A test passes when it reaches its end without panicking.
  • #[should_panic] passes only when the code inside panics.

In this example, grade turns a score into the word pass or fail. main prints one result and points at the real checker. Three tests sit below. Two of them check grade with assert_eq!. The third expects a panic, and the index scores[5] panics, because the Vec holds only two scores. A real cargo test run of this file reports "3 passed" — the panicking test passes too, because its panic was expected. Rust Testing, in the Intermediate course, goes deeper from here — organising tests, and tests that live outside the code they check.

Note

In Rust, testing is part of the language and its tools, not an extra library to install.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Rust Playground

Exercise

A test reaches its end without panicking. What does the report call it?