1 测试入门
1.1 增加测试代码
#[cfg(test)]mod tests { #[test] fn exploration() { assert_eq!(2 + 2, 4); }}
1.2 运行测试
- 用
cargo test命令执行测试 - 每个测试函数在单独的线程中运行,一个测试不通过不会影响其他测试
E:\RustProjects\playground>cargo test Finished dev [unoptimized + debuginfo] target(s) in 0.02s Running target\debug\deps\playground-73f3d496fde692d7.exerunning 1 test// 测试模块名::测试函数名test tests::exploration ... ok// measured 用于性能测试// filtered out 指示被过滤而不运行的测试数量test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
1.3 用于测试的宏
assert!、assert_eq!、assert_ne!的最后一个可选参数用于指定用户定义的错误描述- 带前缀
debug_的assert系列宏表示:仅在调试版本有效,或者在指定了编译参数-C debug-assertions时有效 unreachable!- 将
#[should_panic]加在测试函数前面,表示要求测试函数panic! #[should_panic(expected = "Guess value must be less than or equal to 100")]可以带第二个参数,表示预期的错误文本,避免放过其他未预期的错误
2 控制测试运行
cargo test --help显示帮助cargo test <给cargo test的参数> -- <给编译生成的测试二进制程序的参数>- 设置并行度为1,让多个测试函数串行执行:
cargo test -- --test-threads=1 - 默认情况下,如果测试通过,则不显示测试函数的输出;
cargo test -- --nocapture表示对于通过测试的函数,也输出函数的打印输出 cargo test <测试函数名称>用于仅运行指定名称的测试函数,其中<测试函数名称>可以是函数名称的一部分(子串)- 通常情况下不会运行用
#[ignore]标记的测试函数,而cargo test -- --ignored表示仅运行被标记为#[ignore]的测试函数
pub fn add_two(a: i32) -> i32 { a + 2}#[cfg(test)]mod tests { use super::*; #[test] fn add_two_and_two() { assert_eq!(4, add_two(2)); } #[test] fn add_three_and_two() { assert_eq!(5, add_two(3)); } #[test] fn one_hundred() { assert_eq!(102, add_two(100)); }}
3 测试代码的组织
3.1 单元测试
- 标记为
#[test]的函数不会被编译到二进制程序中,而仅用于测试 - 标记为
#[cfg(test)]的模块不会被编译到二进制程序中,而仅用于测试 - 使用测试模块的好处是:可以增加一些测试辅助函数,而这些函数不会被编译到二进制程序中
3.2 测试私有函数
- 根据第7章描述的访问控制规则
- 测试函数可以访问所在模块的其他私有函数
- 测试模块可以访问父模块的私有函数
- 所以:测试函数可以测试私有函数。测试模块可以用
use super::*来简化对父模块私有函数的访问。
pub fn add_two(a: i32) -> i32 { internal_adder(a, 2)}fn internal_adder(a: i32, b: i32) -> i32 { a + b}#[cfg(test)]mod tests { use super::*; #[test] fn internal() { assert_eq!(4, internal_adder(2, 2)); }}
3.3 集成测试
- 在项目根目录创建一个
tests目录,与src目录同级,在tests目录中存放所有集成测试文件 - 必须用
extern crate <包名>导入被测试的包
3.3.1 可执行项目的测试
- 对于二进制项目,如果只有
src/main.rs,则集成测试代码没法将程序代码作为crate导入(只有),没法进行测试 - 所以,建议对于二进制项目,也将主要代码放在
src/lib.rs中,以方便编写集成测试代码