Rust Doctest Options
Doctest annotations are words after the opening ``` fence that steer the test run of a doc comment code block. One word can skip the test.
Pin the edition
This block is always compiled as 2021 code:
/// ```edition2021
/// assert_eq!(2 + 2, 4);
/// ```Skip on one kind of machine
This block is ignored on x86_64 targets only:
/// ```ignore-x86_64
/// assert!(true);
/// ```no_run: compile, never run
This block must compile, but running it would never finish — so the tests only compile it:
/// ```no_run
/// loop {}
/// ```compile_fail: it must not compile
This block is a deliberate mistake. The test passes only because the compiler rejects it:
/// ```compile_fail
/// let x: i32 = "text";
/// ```Using ? inside a doctest
A doctest has no main of its own, so ? has nowhere to return to. Give it one — and hide the wrapper lines with # so readers never see them.
/// ```
/// use std::num::ParseIntError;
/// # fn main() -> Result<(), ParseIntError> {
/// let n: i32 = "42".parse()?;
/// assert_eq!(n, 42);
/// # Ok(())
/// # }
/// ```Example
/// Adds two numbers and returns the sum.
///
/// # Examples
/// A plain block is compiled and run as a test:
/// ```
/// assert_eq!(add(2, 3), 5);
/// ```
/// This block must panic to pass:
/// ```should_panic
/// panic!("shown on purpose");
/// ```
fn add(a: i32, b: i32) -> i32 { a + b }
fn main() { println!("add(2, 3) = {}", add(2, 3)); }Key points
- A doctest annotation is a word that steers how a doc code block is tested.
- Write the annotation right after the opening fence: ```no_run — and several annotations can be combined with commas
- Use ```ignore for an example that cannot run yet.
- It is never compiled.
- The page still shows it.
- But nothing checks it.
- So it can quietly rot
- Use ```text for blocks that are not Rust at all.
- A terminal command is one example.
- Sample output is another.
- Then rustdoc never tries to test them
- cargo test --doc reports each doctest by its kind.
- The kinds are ok and ignored.
- They include compile, should panic, and compile fail.
- It is a quick way to check promises.
- You can see every promise being kept
- The line itself may need to begin with a single #.
- Then start the line with ##.
- The first # is the escape.
- So ##tag runs.
- It renders as #tag
In this example, one small function carries two doctests with different promises. The first block is plain: cargo test compiles it and runs it, and assert_eq! checks that add(2, 3) equals 5. The second block carries should_panic: its panic! is not a failure but the whole point, so the test passes because the code panics. main itself just prints add(2, 3) = 5, agreeing with the first doctest. In a real library, cargo test --doc would report both blocks as ok. One is a normal run. One is "should panic". The plain block must first bring add into scope. A doctest compiles as its own little program. So real libraries add a hidden line. The line looks like # use my_crate::add;. It sits at the top of the block. The # keeps that line off the page.
Note
Annotations are promises the test suite keeps checking — except ignore and text, which promise nothing.
Prefer no_run or compile_fail whenever the code can still be compile-checked.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
An example opens a network connection and waits for an answer. It must keep compiling, but tests should never actually run it. Which annotation fits?