C15: Writing Automated Tests Flashcards
Basic test
[cfg(test)]
Filename: src/lib.rs
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
#[test] fn larger_can_hold_smaller() { let larger = 1 > 8; assert!(larger); } }
$ cargo test
Compiling adder v0.1.0 (file:///projects/adder)
Finished test [unoptimized + debuginfo] target(s) in 0.57s
Running unittests src/lib.rs (target/debug/deps/adder-92948b65e88960b4)
running 2 test
test tests::it_works … ok
test tests::larger_can_hold_smaller … ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
Adding Custom Failure Messages
[test]
fn greeting_contains_name() { let result = greeting("Carol"); assert!( result.contains("Carol"), "Greeting did not contain name, value was `{}`", result ); }
Checking for Panics with should_panic
[cfg(test)]
pub struct Guess {
value: i32,
}
impl Guess {
pub fn new(value: i32) -> Guess {
if value < 1 || value > 100 {
panic!(“Guess value must be between 1 and 100, got {}.”, value);
}
Guess { value } } }
mod tests {
use super::*;
#[test] #[should_panic] fn greater_than_100() { Guess::new(200); } }
Using Result<T, E> in Tests
[cfg(test)]
mod tests {
#[test]
fn it_works() -> Result<(), String> {
if 2 + 2 == 4 {
Ok(())
} else {
Err(String::from(“two plus two does not equal four”))
}
}
}
Running Tests in Parallel or Consecutively
If you don’t want to run the tests in parallel or if you want more fine-grained control over the number of threads used, you can send the –test-threads flag and the number of threads you want to use to the test binary. Take a look at the following example:
$ cargo test – –test-threads=1
Showing Function Output
cargo test – –show-output
Running a Subset of Tests by Name
cargo test <test_name></test_name>
Ignoring Some Tests Unless Specifically Requested
[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[ignore]
fn expensive_test() {
// code that takes an hour to run
}
cargo test – –ignored
Show ignored tests
cargo test – –include-ignored
[cfg(test)]
The #[cfg(test)] annotation on the tests module tells Rust to compile and run the test code only when you run cargo test, not when you run cargo build.
Testing Private Functions
[cfg(test)]
pub fn add_two(a: i32) -> i32 {
internal_adder(a, 2)
}
fn internal_adder(a: i32, b: i32) -> i32 {
a + b
}
mod tests {
use super::*;
#[test] fn internal() { assert_eq!(4, internal_adder(2, 2)); } }
The tests Directory
adder
├── Cargo.lock
├── Cargo.toml
├── src
│ └── lib.rs
└── tests
└── integration_test.rs
Helpers for tests
[test]
To avoid having common appear in the test output, instead of creating tests/common.rs, we’ll create tests/common/mod.rs. The project directory now looks like this:
├── Cargo.lock
├── Cargo.toml
├── src
│ └── lib.rs
└── tests
├── common
│ └── mod.rs
└── integration_test.rs
Filename: tests/integration_test.rs
use adder;
mod common;
fn it_adds_two() {
common::setup();
assert_eq!(4, adder::add_two(2));
}