主题
测试
单元测试放在被测模块旁,用 #[cfg(test)] 包起来,只在 cargo test 时编译。集成测试放在 tests/,每个文件是独立 crate,只能调用 public API。
rust
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds_two_numbers() {
assert_eq!(add(1, 2), 3);
}
}测试函数返回 Result<(), E> 时可以用 ?,Ok(()) 视为通过。
rust
#[test]
fn reads_config() -> Result<(), std::io::Error> {
let text = std::fs::read_to_string("Cargo.toml")?;
assert!(text.contains("[package]"));
Ok(())
}断言
| 宏 | 用途 |
|---|---|
assert! | 条件为真 |
assert_eq! / assert_ne! | 相等 / 不等,失败时打印两边 |
#[should_panic] | 期望 panic;可加 expected = "..." 匹配信息 |
比较复杂结构时给类型派生 Debug + PartialEq。浮点比较不要直接 assert_eq!,改用误差范围。
命令
bash
cargo test
cargo test adds_two_numbers # 名称过滤
cargo test --lib # 只跑库的单元测试
cargo test -- --nocapture # 打印 stdout文档注释里的代码块也是测试:
rust
/// Adds two numbers.
///
/// ```
/// assert_eq!(demo::add(1, 2), 3);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}文档测试以 crate 外部身份编译,只能看到 pub 项,适合锁住公开 API 的示例。
异步测试由运行时提供宏,例如 #[tokio::test]。需要启动运行时的测试不要在同步 #[test] 里自行 block_on,除非在测运行时本身。
