Rust学习_6.测试
测试
一、如何编写测试
- 准备所需的数据或状态;
- 调用需要测试的代码;
- 断言运行结果与我们期望的一致;
二、测试函数的构成
- 测试:一个标注有test属性的函数;
- 每个测试运行时都处于独立的线程中,主线程在监视测试线程时,一旦发现测试线程意外终止,就会将对应的测试标记为失败。
三、测试宏
assert!
: 确保测试中某些条件的值为true
;assert_eq!
和assert_ne
判断相等性;- 方法的参数必须同时实现
PartialEq
和Debug
两个trait.
- 方法的参数必须同时实现
should_panic
:确认代码是否按照预期处理错误。- 添加可选参数
expected
:检查panic
发生时输出的错误提示信息是否包含了指定的文字。
- 添加可选参数
四、添加自定义的错误提示信息
自定义的错误提示信息可以很方便地记录当前断言的含义,更容易知道代码出了什么问题。
1 |
|
五、在测试中使用 Result<T,E>
- 无需panic,可使用Result<T,E>作为返回类型编写测试:
- 返回OK:测试通过;
- 返回Err:测试失败;
- 注意:不要在使用
Result<T,E>
编写的测试上标注#[should_panic]
1 |
|
六、控制测试如何运行
- 改变
cargo test
的行为:添加命令行参数 - 默认行为:
- 并行运行
- 所有测试
- 成功不显示
println!
;
1. 命令行参数
- 针对
cargo test
的参数:紧跟cargo test
后cargo test --help
- 针对测试可执行程序:放在
--
之后cargo test -- --help
cargo test -- --show-output
cargo test -- --test-threads
2. 忽略某些测试,运行剩余测试
ignore
属性1
2
3
4
5
6
7
8
9
fn result_test()->Result<(),String> {
if 2+2==4{
Ok(())
}else{
Err(String::from("tow plus tow does not equal four"))
}
}
3. 运行被忽略的测试:
cargo test -- --ignored
七、测试组织
- Rust 对测试的分类:
- 单元测试
- 集成测试
1. 单元测试
- 小、专注
- 一次对一个模块进行隔离测试
- 可以测试
private
接口
2. 集成测试
- 在库外部。和其他外部代码一样使用你的代码
- 只能使用
public
接口 - 可能在每个测试中使用到多个模块
- 目的:测试被测试库的多个部分是否能正确的一起工作
- 集成测试的覆盖率很重要
2.1 tests 目录
创建和src
同级的目录tests
,cargo会自动在这个目录下寻找集成测试文件。
cargo在编译时会将tests目录下的每个文件的都处理为一个独立的包crate。
2.2 运行指定的集成测试
- cargo test 函数名:运行一个特定的集成测试
- cargo test –test 文件名:运行某个测试文件内的所有测试
3. 针对二进制包的集成测试
如果项目是 binary crate,只含有
src/main.rs
没有src/lib.rs
:- 不能在
tests
目录下创建集成测试; - 无法把
main.rs
的函数导入作用域;
- 不能在
只有
library crate
才能暴露函数给其他 crate 用
这就是Rust的二进制项目经常会把逻辑编写在src/lib.rs
文件中,而只在src/main.rs
文件中进行简单调用的原因。