14.2 文档测试
听
Rust 将文档与代码紧密结合,其文档注释(doc comments)不仅用于生成 API 文档,还能直接嵌入可执行的示例代码。这些示例通过 文档测试(doctest)机制自动编译和运行,确保文档始终与代码行为一致,避免“过时文档”这一常见问题。
编写文档测试
使用 /// 或 //! 注释中的代码块即可定义 doctest:
/// Adds two integers together.
///
/// # Examples
///
/// ```
/// use my_crate::add;
///
/// assert_eq!(add(2, 3), 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
当运行 cargo test 时,Rust 会自动提取所有文档中的代码块,将其包装为独立测试函数并执行。若示例无法编译或断言失败,测试将报错。
代码块的类型
Rust 根据代码块是否以 # 开头或包含特定标记判断其用途:
- 普通示例:会被完整编译和运行;
- 隐藏行:以
#开头的行在生成文档时被隐藏,但参与编译:
上述写法常用于绕过/// ``` /// # fn main() { /// let x = 5; /// assert_eq!(x, 5); /// # } /// ```main函数限制或隐藏样板代码; - 忽略测试:使用
no_run、ignore或compile_fail控制行为:/// ```no_run /// // 会编译但不运行(如涉及 I/O) /// std::fs::read_to_string("file.txt").unwrap(); /// ``` /// /// ```compile_fail /// // 预期编译失败(用于演示错误用法) /// let _ = add("a", "b"); /// ```
模块与路径
文档测试在独立的上下文中运行,因此必须显式引入所需项。常见做法是在示例开头添加 use 语句:
/// ```
/// use my_crate::{Config, parse_config};
///
/// let cfg = parse_config("input");
/// assert!(cfg.is_ok());
/// ```
对于二进制 crate(无 public API),可在 src/main.rs 顶部使用 #![doc(test(no_crate_inject))] 并手动指定 extern crate,但更推荐将核心逻辑移至 lib.rs 以便测试。
最佳实践
- 所有公共 API 应包含至少一个可运行的示例;
- 示例应简洁、自包含,并展示典型用法;
- 避免在文档测试中使用外部依赖或文件系统操作(可用
no_run); - 利用
#隐藏辅助代码,保持文档清晰; - 定期运行
cargo test --doc单独验证文档测试。
小结
文档测试是 Rust “文档即契约”理念的体现。它不仅提升了文档的可信度,还鼓励开发者编写可验证的使用示例。通过将示例纳入测试套件,Rust 有效防止了文档与实现脱节的问题。合理利用 doctest,既能提高库的易用性,又能增强整体质量保障体系。
#Rust 入门教程
分享于 5 天前
上一篇:14.1 单元测试与集成测试
下一篇:14.3 mock 与依赖注入