Rust 文档测试
文档注释中的可运行示例如何保证文档与代码同步;cargo test 运行 doctest。
#concept
#growing
#dev
#rust
[!info] related notes
Rust 文档测试
这个概念为什么出现
文档会腐。
Rust 把 markdown 代码块当测试跑,迫使公共示例保持可编译。
[!abstract] 一句话理解
///文档里的 ``` 示例默认由cargo test编译运行;文档即契约的一部分。
最小可运行示例
场景:库函数文档自带可运行示例
创建库项目 cargo new --lib tax-demo --vcs none,进入目录,将 src/lib.rs 替换为:
/// 计算含税价,税额按整数单位向下取整。
///
/// # Examples
///
/// ```
/// use tax_demo::with_tax;
/// assert_eq!(with_tax(1000), 1100);
/// ```
pub fn with_tax(net: u32) -> u64 {
u64::from(net) + u64::from(net) / 10
}
运行 cargo test --doc 应实际执行一个 doctest;把断言预期改错应失败。示例调用真实公共函数,不用重复算式代替 API。库包名 tax-demo 在 Rust 路径中写作 tax_demo。
结合场景再看三个关注点
- 示例应反映真实调用
ignore/no_run/should_panic属性 控制行为- 隐藏行
#可放 setup
核心概念与准确模型
- doctest 默认像独立 crate 用公共 API
- no_run 仍编译但不运行;ignore 默认跳过,可能连编译问题也隐藏;compile_fail 要求编译失败;错误码匹配依赖 nightly rustdoc,稳定工具链不能据此保证失败原因
cargo test --doc只跑文档测
设计动机
- 防文档撒谎
- 示例即教程
- 与 rustdoc 渲染一体
边界与误区
- 能构造离线输入时优先真正执行;需要网络或密钥的示例可 no_run 保留编译验证,仅确实无法编译时考虑 ignore 并说明
- Cargo 通常对库 target 执行 doctest,纯 bin 的文档注释不会自动提供同等验证;应把可复用 API 放到 lib 并核对测试数量
- 过长示例不适合塞进签名文档
[!warning] 常见误区:文档示例调用私有项 doctest 以外部用户视角。
工程实践
- 公共函数至少一短例
- CI 跑
--doc - 复杂教程放 book/examples
- 失败即修文档或代码
本节总结
- 文档可执行
- cargo test 覆盖
- 公共 API 质量抓手
自测题
- 为何 doctest 访问不了私有函数?
no_run适用?
参考答案
- 模拟外部用户。
- 要展示能编译但不想执行的代码(如启服务器)。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| The Book — Doc Comments | 官方书 | 文档 |
| rustdoc book | 官方 | rustdoc |