11.9 单元测试
11.9.1. 测试的分类
Rust把测试分为两类:单元测试和集成测试。
- 单元测试比较小也比较专注。每一个都单独测试一个模块,还可以测试私有接口。
- 集成测试完全位于代码库之外。它们使用你的代码的方式和其他外部代码一样。集成测试只能访问公共接口,并且每个测试可能用到多个模块。
11.9.2. #[cfg(test)]标注
单元测试的目的是把一小段代码隔离出来,从而快速判断它的行为是否符合预期。我们通常把单元测试和被测试的代码放在src下的同一个文件中。
按照惯例,每个源文件还应有一个test模块来存放这些函数,并用#[cfg(test)]标注测试模块。带有这个标注的代码只有在执行cargo test时才会被编译和运行;运行cargo build时不会编译。
以上是单元测试的规则。集成测试位于不同的目录,因此不需要#[cfg(test)]标注。
#[cfg(test)]中的cfg是configuration(配置)的缩写。使用它相当于告诉Rust:被标注的条目只有在指定的配置选项下才会被包含。
看个例子:
#![allow(unused)]
fn main() {
pub fn add(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}
}
#[cfg(test)]中的配置选项是test。这个配置选项由Rust提供,用于编译和运行测试;只有在执行cargo test时,才会编译和运行#[cfg(test)]下的条目。
11.9.3. 测试私有函数
Rust允许测试私有函数,其他语言不一定如此。
看个例子:
#![allow(unused)]
fn main() {
pub fn add_two(a: usize) -> usize {
internal_adder(a, 2)
}
fn internal_adder(left: usize, right: usize) -> usize {
left + right
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn internal() {
let result = internal_adder(2, 2);
assert_eq!(result, 4);
}
}
}
即使internal_adder没有用pub声明为公共,它仍然可以在测试模块中被调用。