Skip to content

测试

单元测试放在被测模块旁,用 #[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,除非在测运行时本身。

基于 MIT 许可发布