一、并行测试与串行测试
Rust 的测试默认会并行执行,这样能显著减少运行整套测试的时间。不过,如果测试之间存在共享状态(例如同一文件名、环境变量或工作目录)就可能发生相互干扰,导致结果不可预期。因此,当需要避免并行执行时,可以通过下述方式将测试改为单线程串行运行:
cargo test -- --test-threads=1
--test-threads
参数告诉测试运行器使用多少个线程来并行执行测试。将其设置为 1
即可让所有测试顺序地依次运行,杜绝并行冲突。如果项目中仅有一部分测试彼此存在冲突,也可以通过其他方式隔离它们(比如让测试使用不同的临时文件名、路径等),继续保持其它测试并行执行,从而在准确性与速度之间取得平衡。
二、查看测试输出
Rust 的测试运行器默认会“捕获”通过 println!
等方式打印到标准输出的内容。也就是说,如果测试通过了,你通常不会看到这些输出。如果你希望在测试通过时也能看到打印结果,只需在执行测试时添加 --show-output
:
cargo test -- --show-output
这样就算测试通过,也能在终端看到输出的所有内容。如果你没有使用此参数,那么只有在测试失败时,运行器才会把测试产生的输出打印到屏幕,方便你进行排查。
举个例子,下面是一段带有输出的示例测试:
fn prints_value(x: i32) -> i32 {println!("I got the value {}", x);10
}#[cfg(test)]
mod tests {use super::*;#[test]fn test_pass() {assert_eq!(prints_value(4), 10);}#[test]fn test_fail() {assert_eq!(prints_value(8), 8);}
}
- 不加
--show-output
:你只会在失败的测试中看到输出,比如“I got the value 8
”。 - 加
--show-output
:你能同时看到成功和失败的测试输出,包含“I got the value 4
”和“I got the value 8
”。
三、按名称筛选要运行的测试
在大型项目中,我们可能并不想每次都运行全部测试。cargo test
允许你通过传递测试名称或其一部分来筛选只运行部分测试。
1. 运行单个测试
假设我们有如下三个测试函数:
#[cfg(test)]
mod tests {use super::*;#[test]fn add_two_and_five() {assert_eq!(add_two(5), 7);}#[test]fn add_two_and_one_hundred() {assert_eq!(add_two(100), 102);}#[test]fn add_two_and_negative() {assert_eq!(add_two(-2), 0);}
}
如果只想运行 add_two_and_five
测试,可以执行:
cargo test add_two_and_five
它会精确匹配测试函数名(或包含该字符串的测试名),因此只运行 add_two_and_five
,而跳过其它测试。
2. 模糊匹配运行多个测试
当你只指定了部分字符串(例如 add_two
),那么所有函数名包含该子串的测试都会被执行:
cargo test add_two
这样就能一次性跑 add_two_and_five
、add_two_and_one_hundred
、add_two_and_negative
三个测试。对于模块名也同理,如果模块名中包含了指定子串,也会匹配该模块下所有测试。
四、忽略某些测试
有些测试用例可能相当耗时(例如需要访问网络或执行性能基准),并且在日常开发阶段你并不希望每次都运行它们。可以在对应的测试函数上添加 #[ignore]
,这样执行 cargo test
时会默认跳过它们:
#[test]
#[ignore]
fn expensive_test() {// 可能做一些庞大运算或网络操作
}
执行时,你会看到类似以下结果:
running 1 test
test expensive_test ... ignored
1. 运行被忽略的测试
如果需要只运行或包括忽略测试,有以下两种方式:
- 只运行被忽略的测试:
cargo test -- --ignored
- 运行所有测试(包含被忽略的):
cargo test -- --include-ignored
如此便可在不同场景下快速切换测试范围,节省时间又保证在需要的时候验证所有功能。
五、结语
Rust 的测试生态既简单又强大,默认为你并行执行测试并捕获输出,让结果更易读。但在实际开发中,往往需要对执行流程进行微调,例如:
- 调整并行度:避免共享资源冲突或提升执行效率。
- 查看完整输出:方便调试,即使测试通过也能看到关键性日志。
- 按名称过滤测试:加快反馈速度,聚焦当前工作范围。
- 忽略特定测试:在常规开发中跳过耗时场景,之后再做专项验证。
通过结合 cargo test
提供的命令行参数以及对测试函数进行适当标注,开发者可以轻松地兼顾测试执行的灵活性与可维护性。随着项目规模的不断扩大,这些技巧将大大提升你的日常调试与验证效率。
希望本篇能够帮助你更好地掌控 Rust 测试的执行方式,写出更严谨、稳定的代码!Happy Testing!