Yeda AI Tips · #088

Español

Make Docs Executable: Doc Tests

What if wrong documentation broke your build? Docs rot: the example in your README drifts from the real API, and nobody notices until a user copies it and files a confused bug report. Doc tests flip the incentive — the examples in your comments and README compile and run as part of the test suite, so stale documentation fails CI instead of failing your users. Your docs cannot lie, because they have to run.

How Rust doc tests work

Every fenced code block inside a /// doc comment is a test. cargo test runs them alongside your unit tests; cargo test --doc runs only the doc tests.

/// Adds two numbers.
///
/// ```
/// let sum = mycrate::add(2, 3);
/// assert_eq!(sum, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 { a + b }

Rustdoc preprocesses each block so short examples stay short: it wraps the code in fn main() if you didn't write one and injects extern crate mycrate; for you. Rename add later and this block stops compiling — the build goes red before the docs go wrong.

Lines starting with # compile but don't render, so readers see 2 lines of signal while the compiler sees the full setup:

/// ```
/// # fn setup() -> mycrate::Client { mycrate::Client::new() }
/// let client = setup();
/// client.ping();
/// ```

Not every example should run the same way

Some examples hit the network, some are deliberately broken, some must crash. Rustdoc gives each block an attribute instead of an excuse:

AttributeWhat it doesUse when
(none)Compile and runThe default — prefer it
no_runCompile, don't executeNetwork calls, side effects
should_panicMust panic to passDocumenting failure modes
compile_failMust fail to compileShowing what the type system rejects
ignoreSkip entirelyLast resort — it proves nothing

compile_fail is the underrated one: it lets you document "this misuse won't compile" and have CI verify that the misuse still doesn't compile.

Test the README too

The README is the doc that drifts fastest, because it lives outside the compiler's sight. Pull it in:

#[doc = include_str!("../README.md")]
#[cfg(doctest)]
pub struct ReadmeDoctests;

Every Rust code block in your README is now a doc test. The #[cfg(doctest)] gate keeps the struct out of your public API and rendered docs.

Same idea outside Rust

The principle is language-agnostic — executable examples predate Rust by decades:

Power-user moves

Resources

Building an AI feature? Yeda AI designs, audits, and ships production LLM systems.

Talk to us · Read the blog · Leer en español