Saturday, June 10, 2023

Testing in Rust


 


In this post we show an example of testing in rust.



use std::{thread, time};
fn main() {}

// this is our code
mod toys {
use std::{thread, time};

pub struct Toy<'a> {
name: &'a str,
size: u32,
move_time: u64,
}

impl<'a> Toy<'a> {
pub const fn new(name: &'a str, size: u32) -> Self {
if name.len() == 0 {
panic!("name must be supplied")
}
Self {
name,
size,
move_time: (size / 2) as u64,
}
}
pub fn is_bigger(&self, other: Toy) -> bool {
self.size > other.size
}

pub fn how_long_to_get_over_here(&self) -> u64 {
println!("Come here {}", self.name);
thread::sleep(time::Duration::from_secs(self.move_time));
self.move_time
}
}


pub const DINO: Toy = Toy::new("Rex", 10);
pub const CAR: Toy = Toy::new("Mustang", 4);
}


/*
here we add a new module with config `test`.
this means the code will not be included in our final module.
*/
#[cfg(test)]
mod tests {
// as the tested module is in different scope, we need to explicitly include it
use super::toys;

// test functions are annotated with `test`
#[test]
fn size_matters() {
// we can use assert macro to check results
assert!(toys::DINO.is_bigger(toys::CAR));
}

/*
we can mark test functions not to run by default.
this is required, for example, in case the test runs for a long period
*/
#[ignore]
#[test]
fn calling() {
let seconds = toys::CAR.how_long_to_get_over_here();
/*
1. we use assert_eq here. we can also use assert_ne
2. we also add description the the asser macro. this is displayed in case the assert fails
*/

assert_eq!(1, seconds, "should arrive very quickly");
}

// here we add the should_panic annotation which check for an expected panic
#[test]
#[should_panic]
fn must_use_name() {
toys::Toy::new("", 0);
}
}


Now we run the tests:

$ cargo test
Compiling rust1 v0.1.0 (/home/alon/git/rust1)
warning: unused imports: `thread`, `time`
--> src/main.rs:1:11
|
1 | use std::{thread, time};
| ^^^^^^ ^^^^
|
= note: `#[warn(unused_imports)]` on by default

warning: `rust1` (bin "rust1" test) generated 1 warning (run `cargo fix --bin "rust1" --tests` to apply 1 suggestion)
Finished test [unoptimized + debuginfo] target(s) in 0.26s
Running unittests src/main.rs (target/debug/deps/rust1-6a33c00b5734b10f)

running 3 tests
test tests::calling ... ignored
test tests::size_matters ... ok
test tests::must_use_name - should panic ... ok

test result: ok. 2 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s


Notice the ignored test are not run. To run the ignore test, we should explicitly ask:

$ cargo test -- --ignored
warning: unused imports: `thread`, `time`
--> src/main.rs:1:11
|
1 | use std::{thread, time};
| ^^^^^^ ^^^^
|
= note: `#[warn(unused_imports)]` on by default

warning: `rust1` (bin "rust1" test) generated 1 warning (run `cargo fix --bin "rust1" --tests` to apply 1 suggestion)
Finished test [unoptimized + debuginfo] target(s) in 0.00s
Running unittests src/main.rs (target/debug/deps/rust1-6a33c00b5734b10f)

running 1 test
test tests::calling ... FAILED

failures:

---- tests::calling stdout ----
Come here Mustang
thread 'tests::calling' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `2`: should arrive very quickly', src/main.rs:71:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
tests::calling

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 2 filtered out; finished in 2.00s

error: test failed, to rerun pass `--bin rust1`







No comments:

Post a Comment