Rust系统编程之自动化测试

1.基础测试模板

1
2
3
4
5
6
7
8
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 6);
}
}

1.1 断言宏

1
2
assert_eq! // ==
assert_ne! // !=

需要要断言的对象实现了PartialEqDebug trait。标准库默认都实现了,自定义类型可以添加#[derive(PartialEq, Debug)] 注解。

1.2 should_panic

1
2
3
4
5
6
7
8
9
10
#[cfg(test)]
mod tests {
use super::*;

#[test]
#[should_panic(expected = "should_panic info")]
fn greater_than_100() {
Guess::new(200);
}
}

在panic时提供额外信息。

1.3 使用Result<T, E>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#[cfg(test)]
mod tests {
fn it_works() -> Result<(), String> {
if 2 + 2 == 4 {
Ok(())
} else {
Err(String::from("two plus two does not equal four"))
}
}
#[test]
fn verify() {
assert!(it_works().is_ok());
}
}

此时可以测试返回Result的函数了。

2.控制测试用例运行

2.1 指定单线程

因为测试用例是默认并发的,可能会出现竞争。使用如下命令指定单线程可以避免这个问题。

1
cargo test -- --test-threads=1

2.2 显示输出

默认测试屏蔽了println!等宏的输出信息,可以使用如下命令开启输出。

1
cargo test --show-output

2.3 运行指定测试用例

指定某个测试用例

1
cargo test xxx

过滤运行多个测试,下面的代码运行所有以pe开头的测试用例

1
cargo test pe

忽略某些测试

1
2
3
4
5
6
7
8
9
10
11
#[test]
#[ignore]
fn expensive_test() {
// 需要运行一个小时的代码
}

// 运行所有被忽略的测试用例
cargo test -- --ignored

// 运行所有的测试用例,包括被忽略的
cargo test -- --include-ignored

3.测试目录组织

3.1 单元测试

一般就是在src的module中直接添加带有测试注解的函数即可,与具体的代码绑定。

3.2 集成测试

一般是在package根目录下建立tests文件夹来编写公开接口的测试用例。

1
2
3
4
5
6
7
8
├── Cargo.lock
├── Cargo.toml
├── src
│ └── lib.rs
└── tests
├── common
│ └── mod.rs
└── integration_test.rs

对于bin crate,建议内部嵌入一个library crate,在main.rs中调用lib.rs的代码,而集成测试只对lib.rs中的接口进行测试。


Rust系统编程之自动化测试
http://helloymf.github.io/2023/04/17/rust-xi-tong-bian-cheng-zhi-zi-dong-hua-ce-shi/
作者
JNZ
许可协议