在Rust中进行集成测试
集成测试是一种独立于代码的测试方式,进行集成测试时,相当于从外部调用库或运行程序,它常用于测试项目整体,而非独立的单元。
集成测试的代码放在根目录下的tests目录中,目录下的每个文件都是独立的包,这意味着测试项目时,就好像使用外部的包一样,需要独立导入,且每个测试文件之间也是独立的。
准备
一些库经常在集成测试中使用,在cargo.toml中加入这些开发依赖:
1  | [dev-dependencies]  | 
截至文章更新时间,这里列出的版本号以及下文的用法均对应最新版本。
 使用tempfile创建临时目录和文件
我们在测试时常常需要使用一些文件与目录,使用临时文件会比使用根目录下指定的文件更好。tempfile包提供了生成临时文件的功能。
1  | use tempfile::{tempfile, tempdir};  | 
 使用assert_cmd测试可执行程序
集成测试中常常需要直接测试可执行程序而非某个库功能,此时可以使用assert_cmd。
假定我们构建的可执行程序的文件名为hello.exe,使用cargo运行需要的指令为cargo run --bin hello。
使用assert_cmd中的Command::cargo_bin("hello")即可达到同样的效果。
控制测试环境
我们常常需要在测试时指定一些环境变量或标准输入内容。Command结构体提供了一些方法,可以定制运行环境。
1  | use asser_cmd::Command;  | 
 使用Assert与Predicate判断测试结果
我们需要获取程序运行的结果并测试是否符合预期,这时可以对Command调用assert()方法获取Assert对象,通过Assert来测试结果。
例如,我们编写了一个从标准输入中读取一个数字,并输出它的平方的程序,可以使用如下方法进行测试。
1  | use assert_cmd::Command;  | 
stdout方法的签名为:
1  | pub fn stdout<I, P>(self, pred: I) -> Self  | 
Predicate是predicate_core中规范的trait,当我们传入"400"时,表示输出内容与其完全匹配。
predicates库包含许多功能强大的Predicate,例如部分匹配,假定我们想要测试使用-V参数后,输出的内容中是否包含程序版本号,我们可以编写如下测试:
1  | use assert_cmd::Command;  | 
除此之外,还常用Assert判断程序是否正确退出。
1  | Command::cargo_bin("bin_fixture")  | 
手动判断测试结果
当我们需要对输出进行复杂的判断时,Assert与Predicate可能无法满足我们的需求。我们可以在Command上调用output方法获取Ouput对象,这个对象保存了程序的stdout和stderr输出,获取输出后可以手动编写判断语句。
1  | let mut output = Command::cargo_bin(env!("CARGO_PKG_NAME"))  | 
基准测试
nightly的Rust自带cargo bench基准测试功能,但自带的基准测试事实上已经被deprecated了,不会出现在stable中。更推荐使用criterion库进行基准测试。
1  | pub fn criterion_benchmark(c: &mut Criterion) {  |