编写自动化测试
如何编写测试
Hello world
rust
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
运行:
bash
$ cargo test
断言宏
assert!
: 真假assert_eq!
:是否相同assert_ne!
:是否不相同
如果失败,内部会调用panic!
;assert会在debug和release版本中都生效,debug_assert默认只在非优化构建(非release)的版本中生效
debug_assert!
: 真假debug_assert_eq!
:是否相同debug_assert_ne!
:是否不相同
自定义message
assert
后面的参数, 请看std::fmt
rust
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
// assert with a custom message
let x = true;
assert!(x, "x wasn't true!");
let a = 3;
let b = 27;
assert!(a + b == 301, "a = {}, b = {}", a, b);
}
}
should_panic检查panic
如果程序执行到了panic,表示测试通过
rust
pub struct Guess {
value: i32,
}
impl Guess {
pub fn new(value: i32) -> Guess {
if value < 1 || value > 100 {
panic!("Guess value must be between 1 and 100, got {}.", value);
}
Guess { value }
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic] // should_panic注解
fn greater_than_100() {
Guess::new(200);
}
}
将Result<T, E>
用于测试
Err
可以携带错误信息,在测试失败时,会打印出来
rust
#[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"))
}
}
}
使用Result
同时不能使用should_panic
控制测试运行
bash
# -- 后面的是参数是:传递给二进制的参数
$ cargo test -- --help
# 当运行多个测试时,Rust默认使用线程来并行运行;设置线程数
$ cargo test -- --test-threads=1
# Rust测试库会截获到标准输出的内容;如果测试成功了,就看不到println输出的内容,如果测试失败了,就可以看到相应的println输出内容
# 禁用rust的捕获输出内容,全部的标准输出会打印输出,和测试的成功失败无关
$ cargo test -- --nocapture
# 可以指定运行特定的测试,也可以是匹配(规则:是否包含)
$ cargo test one_hundred
$ cargo test add
# 排除执行使用了#[ignored]注解的测试
$ cargo test -- --ignored
测试的组织结构
单元测试与集成测试
- 单元测试:内部测试一个模块,测试一个私有接口。(对内)
- 集成测试:库对外的接口,别人集成你这个库调用的接口。(对外)
单元测试
#[cfg(test)]
中cfg的意思是,告诉cargo test
时会去编译和运行这部分代码;而cargo build
不会去编译这部分代码,也不会打包到二进程程序中
rust
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));
}
}
集成测试
tests目录,和src同级
bash
adder
├── Cargo.lock
├── Cargo.toml
├── src
│ └── lib.rs
└── tests
└── integration_test.rs
文件名: tests/integration_test.rs
rust
use adder;
#[test]
fn it_adds_two() {
assert_eq!(4, adder::add_two(2));
}
运行:
bash
# 运行所有的测试
$ cargo test
# 运行指定的集成测试
$ cargo test --test integration_test