Rust 单元测试与基准测试:用 cargo test + criterion 把性能说清楚

test12026-10-022 次阅读

测试是 Rust 的一等公民

Rust 的测试无需额外框架,标准库自带 #[test] 与 assert_eq!。跑 cargo test 即可执行全部测试。当性能敏感时,再用 criterion 做基准测试,量化"改了这段之后到底快了多少"。

第一步:单元与断言

测试和被测试代码放在同一 crate,测试模块用 #[cfg(test)] 标注,发布构建时自动剔除。

// src/parser.rs
pub fn parse_size(s: &str) -> Result<u64, String> {
    let (num, unit) = s.split_at(s.len() - 1);
    let n: u64 = num.parse().map_err(|_| "数字解析失败".to_string())?;
    let mul = match unit {
        "K" => 1_000,
        "M" => 1_000_000,
        _ => return Err("未知单位".to_string()),
    };
    Ok(n * mul)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn parses_kilobytes() {
        assert_eq!(parse_size("3K"), Ok(3_000));
    }

    #[test]
    fn rejects_unknown_unit() {
        assert!(parse_size("5X").is_err());
    }

    #[test]
    #[should_panic]
    fn panics_on_bad_number() {
        // 这里演示 should_panic,实际代码返回 Err 不会 panic
        assert_eq!(parse_size("abcK"), Ok(0));
    }
}

第二步:基准测试量化热点

criterion 比标准库的 test::Bencher 更稳定,能画出趋势并检测性能回退。在 benches/ 目录下放基准用例。

// benches/parse_bench.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};

fn bench_parse(c: &mut Criterion) {
    c.bench_function("parse_size", |b| {
        b.iter(|| {
            let _ = black_box(super::parse_size::parse_size("12M"));
        });
    });
}

criterion_group!(benches, bench_parse);
criterion_main!(benches);

在 Cargo.toml 里声明基准目标,然后 cargo bench 运行:

[dev-dependencies]
criterion = "0.5"

[[bench]]
name = "parse_bench"
harness = false

第三步:用 quickcheck 做属性测试

除了固定用例,还能用属性测试随机生成大量输入,验证"对所有 x 都成立"的不变量。例如解析再拼接应保持一致。

use quickcheck_macros::quickcheck;

#[quickcheck]
fn roundtrip(n: u64) -> bool {
    let s = format!("{}K", n);
    parse_size(&s) == Ok(n * 1_000)
}

工程要点

  • 纯函数优先写单测,副作用(IO、时钟)用 trait 抽象后 mock,测试才稳定。
  • cargo test --release 跑出的结果与 debug 差异很大,基准务必用 release。
  • criterion 第一次会采样较久,用 cargo bench -- --quick 快速验证改动方向。
  • 把基准结果按 commit 存下来,CI 里对比,能第一时间发现性能回退而不是上线后才察觉。
T

test1

文章作者

测试是 Rust 的一等公民 Rust 的测试无需额外框架,标准库自带 #[test] 与 assert_eq!。跑...

分类
技术
发布时间
2026-10-02
字数
约 1930 字
阅读
2 次