Rust Lang Book Ch.11 Automated Tests
单元测试
The Rust Programming Language认为,单元测试分为3部分,1. 设置好需要的数据和状态 2. 运行需要测试的代码 3. 检查返回的结果是否如预期。
使用cargo test即可运行以下单元测试。
#[cfg(test)] mod tests { #[test] fn it_works() { assert_eq!(2 + 2, 4); } }
书中建议单元测试用mod test + #[cfg(test)],集成测试则是单独建立一个tests文件夹,与src为兄弟文件夹,此时就不用#[cfg(test)]。但tests文件夹中的每个文件都被认为是一个用于测试的crate,不再有src中的父子结构。比如test/common.rs可能只放了一些用来辅助测试的函数和结构体声明,也会被当成是测试模块。为了避免这一点,必须要用test/common/mod.rs这样的路径来保存这些辅助代码。
纯binary crate,即没有lib.rs的crate,没法用tests文件夹创建集成测试。
#[ignore]能不运行某个测试
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
#[test]
#[ignore]
fn expensive_test() {
// code that takes an hour to run
}
assert!,assert_eq!, assert_ne!宏在这种时候非常有用。
#[cfg(test)] mod tests { use super::*; #[test] fn larger_can_hold_smaller() { let larger = Rectangle { width: 8, height: 7, }; let smaller = Rectangle { width: 5, height: 1, }; assert!(larger.can_hold(&smaller)); } }
#[test]
fn greeting_contains_name() {
let result = greeting("Carol");
assert!(
result.contains("Carol"),
"Greeting did not contain name, value was `{}`",//出错时的提示语
result
);
}
should_panic也十分强大,也能和预期的错误信息做比较
#[cfg(test)] mod tests { use super::*; #[test] #[should_panic] fn greater_than_100() { Guess::new(200); } }
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic(expected = "Guess value must be less than or equal to 100")]
fn greater_than_100() {
Guess::new(200);
}
}
出错时可以直接返回Result::Error
#[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")) } } }
cargo test
cargo test -- --test-threads=1 #并行地运行单元测试 cargo test -- --show-output #显示成功运行的tests的输出 cargo test <test_func_name_pattern> #只运行包含test_func_name_pattern的测试 cargo test -- --ignored #运行被ignored的测试
cargo test -- --test-threads=1