Rust学习笔记
Rust编程语言入门教程课程笔记
参考教材: The Rust Programming Language (by Steve Klabnik and Carol Nichols, with contributions from the Rust Community)
Lecture 11: Writing Automated Tests
src/lib.rs
//Tests: Arrange, Act, Assert
//#[test] attribute tells the compiler to compile and run the code only when running tests//cargo test --test-threads=1 //run tests in parallel or not
//cargo test -- --test-threads=1 //run tests in parallel or not//Test Organization: Unit Tests, Integration Tests
//Unit Tests: tests for one module in isolation at a time
//Integration Tests: tests for multiple modules and how they work togetherpub fn add(left: usize, right: usize) -> usize {left + right
}pub fn add_two(a: i32) -> i32 {a + 2
}#[derive(Debug)]
pub struct Rectangle {width: u32,height: u32,
}impl Rectangle {pub fn can_hold(&self, other: &Rectangle) -> bool {// self.width > other.width && self.height > other.heightself.width < other.width && self.height > other.height}
}pub fn greeting(name: &str) -> String {format!("Hello {}!", name)//String::from("Hello!")
}pub struct Guess {value: u32,
}impl Guess {pub fn new(value: u32) -> Guess {// if value < 1 || value > 100 {// panic!("Guess value must be between 1 and 100, got {}.", value);// }// Guess { value }if value < 1 {panic!("Guess value must be greater than or equal to 1, got {}.",value);} else if value > 100 {panic!("Guess value must be less than or equal to 100, got {}.",value);}Guess { value }}
}fn prints_and_returns_10(a: i32) -> i32 {println!("I got the value {}", a);10
}//Test Private Functions
pub fn add_three(a: i32) -> i32 {internal_adder(a, 3)
}fn internal_adder(a: i32, b: i32) -> i32 {a + b
}//Unit Tests
#[cfg(test)]//only compile and run the following code when we run cargo test (cfg = configuration)
mod tests {use super::*; //we have added use super::*;#[test]fn it_works() {let result = add(2, 2);assert_eq!(result, 4);// assert_eq: macro that compares two values for equalityassert_ne!(result, 5);// assert_ne: macro that compares two values for inequality//If the two values are not equal, these macros will call panic and report the values }#[test]fn it_works2() -> Result<(), String> {if add(2, 2) == 4 {Ok(())} else {Err(String::from("two plus two does not equal four"))}//The Result<(), String> type is a concrete type that implements the //std::error::Error trait, which means we can use ? in the body of this test.}// #[test]// fn another() {// panic!("Make this test fail");//panic! macro that comes with Rust// }#[test]fn larger_can_hold_smaller() {let larger = Rectangle {width: 10,height: 8,};let smaller = Rectangle {width: 5,height: 4,};// assert!(larger.can_hold(&smaller));assert!(!larger.can_hold(&smaller), "smaller can hold larger");//assert! with a custom failure message}#[test]fn greeting_contains_name() {let result = greeting("Carol");// assert!(result.contains("Carol"));assert!(result.contains("Carol"),"Greeting did not contain name, value was `{}`", result);}#[test]//#[should_panic]//#[should_panic] annotation on the test function#[should_panic(expected = "Guess value must be less than or equal to 100")]//#[should_panic] with expectedfn greater_than_100() {Guess::new(200);}#[test]fn this_test_will_pass(){let value = prints_and_returns_10(4);assert_eq!(10, value);//cargo test -- --show-output}#[test]// fn this_test_will_fail(){// let value = prints_and_returns_10(8);// assert_eq!(5, value);// //cargo test will output println! messages// }#[test]fn add_two_and_two(){assert_eq!(4, add_two(2));}#[test]fn add_three_and_two(){assert_eq!(5, add_two(3));}//cargo test add#[test]fn one_hundred(){assert_eq!(102, add_two(100));}//cargo test one_hundred#[test]#[ignore]fn expensive_test(){//code that takes an hour to runassert_eq!(1+1+1+1+1+1+1+1+1+1, 10);}//cargo test -- --ignored#[test]fn internal(){assert_eq!(5, internal_adder(2, 3));//internal_adder is private}}
tests/integration_tests.rs
use adder;
mod common;#[test]
fn it_adds_two() {common::setup();assert_eq!(4, adder::add_two(2));
}//cargo test --test integration_tests
tests/another_integration_tests.rs
use adder;
mod common;
#[test]
fn it_really_adds_two() {common::setup();assert_eq!(4, adder::add_two(2));
}
tests/common/mod.rs
pub fn setup() {// setup code specific to your library's tests would go here
}