cargo test 快速上手
文章目录1.简介2.格式3.选项4.示例4.1 第一个测试4.2 运行指定测试4.3 显示测试输出4.4 测试 panic4.5 测试 Result4.6 忽略测试4.7 集成测试4.9 单线程运行避免输出交错4.10 只编译不运行5.文档测试Doc-tests5.1 核心机制5.2 为什么需要文档测试5.3 常用技巧5.4 注意事项5.5 一句话总结6.小结参考文献1.简介cargo test是 Rust 内置的测试命令用于编译并运行项目中的所有测试单元测试、集成测试、文档测试。它无需额外依赖开箱即用是保证代码质量的第一道防线。特点说明内置支持Rust 标准工具链自带无需安装第三方库多种测试类型支持单元测试、集成测试、文档测试并行执行默认多线程并行运行测试输出捕获默认捕获println!输出失败时才显示过滤运行支持按名称筛选测试2.格式cargotest[OPTIONS][TESTNAME][--[ARGS]...]部分说明[OPTIONS]为 Cargo 层面的选项如--workspace、-p、--release[TESTNAME]测试名称过滤器只运行名称包含该字符串的测试--分隔符后面的参数传给测试二进制而非 Cargo即 cargo test 编译后生成的那个可执行文件它内部包含了所有测试函数由 Rust 测试框架libtest驱动运行。[ARGS]测试二进制层面的参数如--nocapture、--test-threads。3.选项--workspace 运行工作空间内所有成员的测试而不只是当前目录的包。 -p 包名 只运行指定包的测试。与 --workspace 互斥。 --release 在 release 模式下编译并运行测试启用优化。 --all-targets 测试所有目标包括库、二进制、示例和基准测试。 --no-run 只编译测试不运行。适合 CI 中先编译再分步执行。 --no-fail-fast 即使有测试失败也继续运行其他测试而不是立即停止。 --doc 只运行文档测试即文档注释中的代码示例。 --lib 只运行库目标的单元测试。 --test 文件名 只运行指定的测试目标即 tests/ 目录下的某个集成测试文件。 --tests 运行所有设置了 test true 的目标默认包含单元测试与集成测试。 --bins 只运行二进制目标的测试。 --examples 只运行示例目标的测试。 --nocapture 不捕获 println! 等标准输出直接打印到终端。需放在 -- 之后。 --test-threadsN 指定并行线程数N1 表示单线程运行。需放在 -- 之后。 --ignored 只运行被 #[ignore] 标记的测试。需放在 -- 之后。 --include-ignored 运行所有测试包括被忽略的。需放在 -- 之后。 --exact 精确匹配测试名称而非子串匹配。需放在 -- 之后。 --list 列出所有测试名称不运行。需放在 -- 之后。 --show-output 显示成功测试的输出。需放在 -- 之后。 --skip 名称 跳过名称匹配的测试。需放在 -- 之后。其中--tests是运行所有被配置为测试目标的构建单元而不仅仅是 tests/ 目录下的集成测试。一个 Cargo 项目里可能被标记为 test true这是默认值的目标包括目标类型位置是否默认被--tests选中集成测试tests/目录下的每个.rs文件✅ 是库的单元测试src/lib.rs或src/下的模块用#[cfg(test)]标记✅是二进制的单元测试src/main.rs或src/bin/下的文件✅是示例如果配置了test trueexamples/目录✅ 是如果显式配置所以cargo test --tests会运行库和二进制里的单元测试以及tests/目录下的集成测试。它和直接cargo test的主要区别在于--tests通常会跳过文档测试Doc-tests因为文档测试是由rustdoc处理的不属于 Cargo 的“测试目标”概念。4.示例4.1 第一个测试// src/lib.rspubfnadd(a:i32,b:i32)-i32{ab}#[cfg(test)]modtests{usesuper::*;#[test]fntest_add(){assert_eq!(add(2,3),5);}}cargotest注意mod tests 里的 tests 只是一个模块名你可以取任何合法的 Rust 标识符不过约定俗成使用 tests。#[cfg(test)]modmy_tests{// ✅ 合法#[test]fntest_add(){...}}#[cfg(test)]modunit_tests{// ✅ 合法#[test]fntest_add(){...}}#[cfg(test)]mod测试模块{// ✅ 合法Rust 支持 Unicode 标识符#[test]fntest_add(){...}}4.2 运行指定测试# 只运行名称包含 test_add 的测试cargotesttest_add# 精确匹配测试名称cargotesttest_add ----exact4.3 显示测试输出#[test]fntest_with_output(){println!(开始测试);assert_eq!(22,4);println!(测试结束);}# 默认看不到 println! 输出cargotest# 加 --nocapture 后可以看到cargotest----nocapture4.4 测试 panicfndivide(a:i32,b:i32)-i32{ifb0{panic!(除数不能为 0);}a/b}#[test]#[should_panic(expected 除数不能为 0)]fntest_divide_by_zero(){divide(10,0);}4.5 测试 Result让测试函数返回 Result 类型用 ? 运算符来传播错误而不是用 assert! 或 panic! 来断言。#[test]fntest_parse()-Result(),String{letn:i3242.parse().map_err(|e|e.to_string())?;assert_eq!(n,42);Ok(())}如果 parse() 失败? 会提前返回 Err(e)测试失败并打印 e。如果全部通过返回 Ok(())测试通过。4.6 忽略测试#[test]#[ignore]fntest_slow(){// 耗时测试}# 只运行被忽略的测试cargotest----ignored# 运行所有测试包括被忽略的cargotest-- --include-ignored4.7 集成测试tests/ └── integration_test.rs// tests/integration_test.rsusemy_crate::add;#[test]fntest_add_integration(){assert_eq!(add(2,3),5);}# 只运行指定集成测试文件tests/integration_test.rscargotest--testintegration_test# 只运行指定集成测试文件中的指定测试函数cargotest--testintegration_test test_add_integration4.9 单线程运行避免输出交错cargotest----nocapture--test-threads14.10 只编译不运行cargotest--no-run适合在 CI 中先编译测试再分步运行。5.文档测试Doc-tests文档测试Doc-tests是 Rust 中一种独特的测试方式把文档注释里写的代码示例当作真正的测试来编译和运行。5.1 核心机制你在///文档注释或//!模块文档中写的 Markdown 代码块用三个反引号包裹Rust 的rustdoc工具会自动提取它们编译成独立的测试程序并执行。/// 计算两个数的和。////// # Examples////// /// let result my_crate::add(2, 3);/// assert_eq!(result, 5);/// pubfnadd(a:i32,b:i32)-i32{ab}运行cargo test时输出中会有一个专门的Doc-tests部分Doc-tests my_crate running 1 test test src/lib.rs - add (line 7) ... ok5.2 为什么需要文档测试原因说明保证示例正确文档里的示例是给用户看的如果示例因为 API 变更而失效文档就会误导人。文档测试强制保证示例真实可运行。比文字更可靠文字描述可能过时但代码示例一旦编译失败测试就会报错。提升文档质量写文档测试会倒逼你把示例写得简洁、可运行间接提升文档的可读性。5.3 常用技巧技巧写法说明只跑文档测试cargo test --doc跳过单元测试和集成测试只跑文档示例隐藏辅助代码行首加#该行在文档中隐藏但参与编译测试标记预期失败rust,should_panic这段代码应该 panic否则测试失败标记不运行rust,no_run代码会编译但不会执行隐藏辅助代码示例/// /// # let x 1; // 这一行在文档中隐藏但参与编译/// let y x 1;/// assert_eq!(y, 2);/// 5.4 注意事项注意点说明仅适用于库librarycrate二进制 crate 的文档示例不会被测试编译开销每个文档测试都会编译一次文档示例多时cargo test会变慢需要能访问公开 API文档测试只能使用pub的项不能访问私有函数5.5 一句话总结文档测试 把文档注释里的代码示例当测试跑确保你写的示例永远是正确的。它是 Rust 保证文档质量的独特机制用cargo test --doc可以只跑文档测试。6.小结要点说明测试属性#[cfg(test)]隔离测试模块#[test]标记测试函数断言宏assert!、assert_eq!、assert_ne!panic 测试#[should_panic(expected ...)]Result 测试返回Result用?传播错误忽略测试#[ignore]用--ignored运行私有函数单元测试可测集成测试不可测命名规则test_前缀非强制但推荐输出控制--nocapture显示println!输出参数分隔--之前给 Cargo之后给测试二进制Workspace--workspace跑所有成员-p指定包最佳实践每个公开函数都至少写一个正向用例和一个反向用例测试命名推荐test_前缀 描述性名称提交前跑一遍cargo test。参考文献cargo test - Cargo 手册中文版