Rust testing: Difference between revisions

From wikinotes
No edit summary
Line 17: Line 17:
cargo test tests::add_two_positive_numbers  # run specific test
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 add                              # run all tests with the word 'add' in their name
cargo test --test my_integration_test      # run all tests in 'tests/my_integration_tests'


cargo test -- --show-output                # show printed output (in both passing/failed)
cargo test -- --show-output                # show printed output (in both passing/failed)
Line 23: Line 24:
</blockquote><!-- Running Tests -->
</blockquote><!-- Running Tests -->


= Unit Tests =
= Test Types =
<blockquote>
== Unit Tests ==
<blockquote>
<blockquote>
In rust, it's customary to define your tests in the same file as your code.
In rust, it's customary to define your tests in the same file as your code.
Line 55: Line 58:
</syntaxhighlight>
</syntaxhighlight>


Run your tests
<syntaxhighlight lang="bash">
<syntaxhighlight lang="bash">
cargo test                                 # run all tests
cargo test # run tests
cargo test tests::add_two_positive_numbers  # run specific test
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- Unit Tests -->
</blockquote><!-- Unit Tests -->


= DocComment Tests =
== Integration Tests ==
<blockquote>
Each integration test is it's own crate.<br>
They are written in the <code>tests/</code> directory.
 
<syntaxhighlight lang="rust">
// tests/add_integration_tests.rs
 
use my_code::*;
 
#[test]
fn add_two_positive_numbers() {
    assert_eq!(add(1, 3), 4);
}
</syntaxhighlight>
</blockquote><!-- Integration Tests -->
 
== DocComment Tests ==
<blockquote>
<blockquote>


</blockquote><!-- DocComment Tests -->
</blockquote><!-- DocComment Tests -->
</blockquote><!-- Test Types -->


= Assertions =
= Assertions =

Revision as of 00:26, 9 February 2023

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 --test my_integration_test       # run all tests in 'tests/my_integration_tests'

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

Test Types

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)]       // tell rust not to compile unless testing
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);
    }
}
cargo test  # run tests

Integration Tests

Each integration test is it's own crate.
They are written in the tests/ directory.

// tests/add_integration_tests.rs

use my_code::*;

#[test]
fn add_two_positive_numbers() {
    assert_eq!(add(1, 3), 4);
}

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() {
    // ...
}