Rust testing

From wikinotes
Revision as of 00:07, 9 February 2023 by Will (talk | contribs) (Created page with "= Documentation = <blockquote> {| class="wikitable" |- | tests intro || https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html |- | doc-comment tests || https://doc.rust-lang.org/stable/book/ch14-02-publishing-to-crates-io.html#documentation-comments-as-tests |- |} </blockquote><!-- Documentation --> = Running Tests = <blockquote> By default, tests run in parallel <syntaxhighlight lang="bash"> cargo test # run all tests cargo t...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Documentation

tests intro https://doc.rust-lang.org/stable/book/ch11-01-writing-tests.html
doc-comment tests https://doc.rust-lang.org/stable/book/ch14-02-publishing-to-crates-io.html#documentation-comments-as-tests

Running Tests

By default, tests run in parallel

cargo test                                  # run all tests
cargo test tests::add_two_positive_numbers  # run specific test
cargo test add                              # run all tests with the word 'add' in their name

cargo test -- --show-output                 # show printed output (in both passing/failed)
cargo test -- --ignored                     # only run ignored tests

Unit Tests

In rust, it's customary to define your tests in the same file as your code.

Define your tests

// src/lib.rs

// real code
fn add<T>(a: T, b: T) -> T {
    a + b
}

// test code
#[cfg(test)]
mod tests {
    use super::*;  // include parent module (our src!)

    #[test]
    fn add_two_positive_numbers() {
        let res = add(1, 2);
        assert_eq!(res, 3);
    }

    #[test]
    fn add_a_postive_and_negative_number() {
        let res = add(1, -2);
        assert_eq!(res, -1);
    }
}

Run your tests

cargo test                                  # run all tests
cargo test tests::add_two_positive_numbers  # run specific test

DocComment Tests

Assertions

Some common assertions.

NOTE:

rust doesn't care what order assertion params are defined in.
there is not a convention for one side with expectaton and the other for actual.

assert_eq!(result, expects);            // assert equal
assert_ne!(result, expects);            // assert not equal
assert_eq!(result, "reason", expects);  // add a message to assertion

assert!(result)              // assert true
assert!(!result)             // assert false

You can assert that code panics by assigning an attribute.

// assert any part of code panics
#[test]
#[should_panic]
fn open_non_existant_file_should_panic() {
    // ...
}

// assert panics with message
#[test]
#[should_panic(expected = "foo is not a number")]
fn open_non_existant_file_should_panic() {
    // ...
}

Test functions can also use the Result type.

#[test]
fn open_non_existant_file_should_panic() -> Result<(), String> {
    if add(1, 3) == 4 {
        Ok(())
    } else {
        Err("1 plus 3 should be 4".to_string())
    }
}

Ignore Tests

skip this test

#[test]
#[ignore]
fn open_non_existant_file_should_panic() {
    // ...
}