bigywater.tech
Rust · 158

Doc Test

文档里的示例代码常常过期。Rust 把它们当测试来跑。这篇用真实的 cargo test --doc 验证:哪些代码块会被测、各种标注怎么用、失败长什么样、API 变了会怎样。

6 + 2
这个小库里被运行的文档测试(6 个 ok)与另一组(1 个 compile_fail ok、1 个 ignored)
3 个
重命名 API 后失败的文档测试数
5 种标注
无标注、should_panic、no_run、ignore、compile_fail

每个代码块都是测试

实测 · 本机执行输出
  running 6 tests
  test src/lib.rs - boom (line 32) - compile ... ok
  test src/lib.rs - private_fn (line 55) ... ok
  test src/lib.rs - double (line 12) ... ok
  test src/lib.rs - boom (line 28) - should panic ... ok
  test src/lib.rs - (line 4) ... ok
  test src/lib.rs - double (line 19) ... ok
  test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.01s
  running 2 tests
  test src/lib.rs - boom (line 37) ... ignored
  test src/lib.rs - boom (line 41) - compile fail ... ok
  test result: ok. 1 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.05s

单元与集成测试见单元测试与集成测试。

标注

实测 · 本机执行输出
  测试名(带行号):
    test src/lib.rs - boom (line 32) - compile ... ok
    test src/lib.rs - private_fn (line 55) ... ok
    test src/lib.rs - double (line 12) ... ok
    test src/lib.rs - boom (line 28) - should panic ... ok
    test src/lib.rs - (line 4) ... ok
    test src/lib.rs - double (line 19) ... ok
    test src/lib.rs - boom (line 37) ... ignored
    test src/lib.rs - boom (line 41) - compile fail ... ok

像外部使用者一样

实测 · 本机执行输出
  --list: ['src/lib.rs - (line 4): test', 'src/lib.rs - boom (line 28): test', 'src/lib.rs - boom (line 32): test'] …

失败的文档测试

实测 · 本机执行输出
  退出码 101
  ---- src/lib.rs - triple (line 48) stdout ----
  Test executable failed (exit status: 101).
  stderr:
  thread 'main' (7549991) panicked at /var/folders/km/b69gr9cs3dv8qsm8rjjb4qqc0000gn/T/rustdoctestI4RJa3/doctest_bundle_2024.rs:58:1:
  assertion `left == right` failed
    left: 6
   right: 7
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  failures:
      src/lib.rs - triple (line 48)
  test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 6 filtered out; finished in 0.01s
  running 0 tests
  test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
  all doctests ran in 0.54s; merged doctests compilation took 0.18s

API 变了之后

实测 · 本机执行输出
  把 double 重命名为 twice 之后:
    test src/lib.rs - boom (line 37) ... ignored
    test src/lib.rs - boom (line 32) - compile ... ok
    test src/lib.rs - boom (line 41) - compile fail ... ok
    test src/lib.rs - twice (line 12) ... FAILED
    test src/lib.rs - (line 4) ... FAILED
    test src/lib.rs - twice (line 19) ... FAILED
    test src/lib.rs - boom (line 28) ... ok
    test src/lib.rs - private_fn (line 55) ... ok
    error[E0432]: unresolved import `docs::double`
    error[E0425]: cannot find function `double` in crate `docs`
    error[E0432]: unresolved import `docs::double`
    test result: FAILED. 4 passed; 3 failed; 1 ignored; 0 measured; 1 filtered out; finished in 0.40s

性能测试见Benchmark。

分步演示

文档测试
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / rustc 1.98.1(brew)/ cargo 1.98.1;单个文件用 rustc 直接编译,需要依赖时用 cargo(经代理从 crates.io 下载);计时用 std::time::Instant,数字每次运行会有小幅抖动。edition 2024 的 rustdoc 合并编译行为
    • 没有验证:edition 属性(```edition2021)、文档测试里的 #![feature]、doctest 里使用 dev-dependencies、cfg(doctest)、```text 与其它非 Rust 语言标签、#[doc(test(attr(...)))]、文档测试的并行度与耗时
    京ICP备2026067502号-1京公网安备11010502063487号