企业级测试策略
原理
Rust 测试体系分为三层:
单元测试:#[cfg(test)] mod tests { #[test] fn ... },通常与源码放在同一文件。cargo test 运行所有单元测试。
集成测试:放在 tests/ 目录下,每个文件编译为独立 crate。用于测试公开 API 和黑盒行为。cargo test --test integration_test 运行指定集成测试。
文档测试://! ```rust 代码块在 cargo test 时编译运行,确保 doc 中的示例代码始终有效。
基准测试:#[bench] 在 nightly channel 可用,或使用 criterion crate(稳定渠道)。
测试分层策略
| 层级 | 目标 | 速度 | 覆盖率要求 |
|---|---|---|---|
| 单元测试 | 函数/模块 | 毫秒级 | >80% |
| 集成测试 | 模块间交互 | 秒级 | 关键路径 100% |
| E2E 测试 | 完整业务流程 | 分钟级 | 核心场景 |
| 基准测试 | 性能回归 | 秒-分钟 | 关键热路径 |
Mock 和依赖注入通过 mockall crate 实现自动化 mock 生成。
语法
// 单元测试
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
#[should_panic(expected = "division by zero")]
fn test_divide_by_zero() {
divide(1, 0);
}
}# tests/integration_test.rs — 无需 #[cfg(test)],自动作为测试 crate# benchmark with criterion
[dev-dependencies]
criterion = "0.5"
[[bench]]
name = "my_benchmark"
harness = false// proptest — 属性测试
#[cfg(test)]
mod tests {
use proptest::prelude::*;
proptest! {
#[test]
fn test_add_commutative(a: i32, b: i32) {
assert_eq!(add(a, b), add(b, a));
}
}
}实践
AI 自检
cargo test和cargo test -- --test-threads=1的区别?为何有时需要单线程测试?- proptest 如何自动发现边界情况?shrinking 机制是什么?