Guide

Testing Rust documentation examples

Use rustdoc and cargo test for Rust examples, and be clear that a passing site scan is not evidence those examples compiled or ran.

Published
Updated
November 10, 2026
Reading time
13 min
Facts checked against
The rustdoc book documentation tests page, cargo test, and the Rust book chapter on documentation comments (November 9, 2026)
Outlined documentation pages with a lime pulse line running out of the stack
On this pageThe short answerWhy Rust documentation examples driftWhat rustdoc tests doChoose attributes that match the promiseInspect warnings as well as resultsRun the checks in CIDefine the evidence for each exampleTriage failures before editingChecklist for Rust documentation testsWhat this does not replaceThe sources we checkedFAQ

The short answer

Use Rust's own documentation tests to check Rust examples. cargo test runs documentation tests by default along with other tests, and cargo test --doc focuses on documentation tests. A regular rustdoc test passes when it compiles and runs without panicking. Put assertions in examples when the result matters, and keep examples that are meant only to compile distinct from examples that are meant to run.

DocsAlive recognizes Rust fences but does not execute them: they are skipped as unsupported-lang. It does not run the Rust compiler, Cargo or rustdoc tests. A passing DocsAlive report is not evidence that Rust examples compiled or ran. Use it for supported Markdown examples on the same site, and retain native Rust checks for the crate and its documentation. The Go guide explains a similar compiled-language limitation.

Why Rust documentation examples drift

A documentation example is a promise about an API in a particular context. A function can be renamed, its arguments can change, or a return value can require different handling. An example that was once correct may no longer compile against the crate readers install. Even when it compiles, an assertion can expose a behavior change that compilation alone cannot detect.

Edition differences matter too. An example may be interpreted under an edition different from the one its author assumed. Record the intended context and use the rustdoc edition attributes when appropriate. Treat an edition choice as part of the test's meaning, not as a decorative label. When a failure appears after an API or edition change, reproduce it with the actual crate and test configuration before changing the prose.

A sample can also compile without ever being run. That may be intentional for a potentially disruptive or environment-dependent operation, but it leaves a different kind of evidence from a normal passing doctest. The distinction matters when a page promises a computed value, an error, or a sequence of effects. A build of the documentation site is useful in its own right, but it cannot establish that a Rust snippet was executed.

Make an inventory of the examples readers encounter: crate documentation, module documentation, README content included in the tested documentation, and separate Markdown pages on the site. Note which test actually reaches each source. A native test for a library's documentation comments does not automatically establish coverage of every separate Markdown page. The README guide and docs testing checklist help make that inventory reviewable.

What rustdoc tests do

rustdoc documentation tests extract examples from documentation and run them as tests. In a regular doctest, successful compilation and execution without a panic produce a pass. An assert_eq! can turn the value promised by a page into a check: if the value changes unexpectedly, the assertion panics and the test fails. A successful run is evidence about the tested example and its environment, not every possible input to the API.

A fenced block without a language is assumed to be Rust by rustdoc. An explicit rust label can make the intent clear when Markdown is also consumed by other tools. The Cargo test reference says cargo test compiles and executes unit, integration and documentation tests; documentation tests run by default and rustdoc extracts samples from library-target documentation comments. cargo test --doc selects the documentation tests. Check your actual test output and configuration to establish which examples were selected.

A README or module page needs the same attention as the main crate page. The Rust book's documentation discussion describes testing documentation comments and including a README in crate documentation. Where a README is included in documentation rustdoc tests, keep it in the native test path. For a separate Markdown page, establish a test path explicitly rather than assuming that a filename alone makes it a doctest.

What rustdoc adds before testing

Rustdoc preprocesses examples to make short samples usable as tests. It inserts common allow attributes, including unused_variables, unused_assignments, unused_mut, unused_attributes and dead_code. It adds attributes configured for documentation tests and leaves leading crate attributes intact. If an example has no extern crate and the relevant crate-injection setting has not disabled it, rustdoc inserts an extern crate for the crate. If the example has no fn main, rustdoc wraps it in one. The rustdoc reference describes the full preprocessing rules.

This convenience is useful, but it affects how you interpret a test. The source displayed to a reader may be shorter than the program rustdoc compiles. If a reader needs a complete program outside that context, show the necessary surrounding structure or explain where it comes from. Do not infer that the displayed fragment is independently runnable in every setting just because its doctest passes.

A small crate example

Suppose the fictional crate acme_docs_demo exposes a function that adds one. A separate Markdown page could show a reader this complete use of the public function:

```rust
use acme_docs_demo::add_one;

let result = add_one(2);
assert_eq!(result, 3);
```

In a crate source file, the function and its documentation test could look like this:

/// Adds one to a number.
///
/// ```
/// use acme_docs_demo::add_one;
/// assert_eq!(add_one(2), 3);
/// ```
pub fn add_one(value: i32) -> i32 {
    value + 1
}

The example is fictional; provide the crate and its test environment in a real project. The assertion makes the expected value explicit. A printed line is not automatically checked merely because prose describes it: use a Rust assertion or another suitable explicit test for the behavior you promise. The separate Markdown fence also needs its own coverage plan if it is not included in the documentation rustdoc tests.

Hide setup without hiding the contract

Rustdoc lets an author hide lines starting with a single # from the displayed example while retaining them for the test. This is useful for setup or assertions that would distract from the concept being taught. For example, the following documentation comment tests the value while showing the use and result assignment to the reader:

/// ```
/// use acme_docs_demo::add_one;
/// let result = add_one(2);
/// # assert_eq!(result, 3);
/// ```
pub fn illustrated() {}

Hidden lines still influence the test. Review them as carefully as visible lines: a hidden import or setup step can make the test pass even though the page fails to tell a reader what they need. Keep the public promise visible in prose or code, and use hidden setup for details that are truly supplied by the surrounding context. The rustdoc reference also describes escaping a leading hash when it should appear in displayed code.

Choose attributes that match the promise

Rustdoc attributes follow the opening fence and determine how a test is interpreted. Choose one based on what the reader should expect, and review it whenever the surrounding example changes.

Attribute Meaning for the example
ignore The example is ignored as a test; record why it needs separate coverage.
should_panic The example must compile and must panic; the test fails if it does not panic.
no_run The example compiles but is not run.
compile_fail Compilation is expected to fail.
edition2015, edition2018, edition2021, edition2024 Select the named Rust edition for the example.
standalone_crate Treat the example as a standalone crate under rustdoc's documented rules.

A negative example marked compile_fail is useful when the documentation explains code that should be rejected. It is not evidence that a valid reader journey runs. Similarly, should_panic checks for a panic rather than a normal return. An ignored example or a compile-only example needs a separate plan if runtime behavior is central to the page. Avoid making a test green by changing its meaning without also changing the promise to the reader.

Inspect warnings as well as results

Rustdoc documents rustdoc --test --test-args=--show-output and cargo test --doc -- --show-output as ways to show warnings in doctests. Unused warnings remain hidden by default; the reference describes enabling them for an example or at the crate root. Showing warnings is useful during maintenance, but the output setting does not turn a compile-only or ignored example into an executed one. Read the attributes and test results together.

A warning may explain a future maintenance problem even when the test passes. Record the actual warning, the affected source and the test environment, then determine whether the example or its surrounding explanation needs a change. A clean-looking output is only as broad as the warnings enabled for that run.

Run the checks in CI

Run the native checks whenever the crate or documentation changes and periodically to notice drift. The following generic shell outline assumes the Rust tools and the product CLI have already been made available during setup. Adapt the selected directory to your repository:

cargo test
cargo test --doc -- --show-output
docsalive scan . --execute --include "docs/quickstart*" --out docs-test-report

The second command makes documentation test output visible; it is not a replacement for inspecting the first command's broader result. The scan covers supported extracted Markdown fences, subject to its plan and skips. It does not execute Rust. Inspect the Markdown and JSON reports to see what was executed, checked or skipped. The CLI reference explains selection and setup; how it works describes the report and triage.

Use a clean environment and record what the test supplied. If setup installs a package or provides a file that readers do not have, decide whether the page should document that prerequisite. Keep steps that depend on each other in reader order, but test independent entry points from a fresh starting state. For a hosted pipeline, the GitLab CI guide and GitHub Actions guide discuss separate job-level checks.

Define the evidence for each example

Before wiring commands into CI, classify the promise made by each example. A positive example may promise that a public function accepts a value and returns a particular result. A negative example may teach that a particular piece of code is rejected. Another may show code that should panic. These are all useful documentation, but they need different expected outcomes. An inventory that records only “tested” loses that distinction.

For a positive example, identify the input, the operation and the observable result. An assertion can check the result directly, while the prose explains why it matters. If the sample has several independent claims, consider whether each one is visible in the test. A test that calls a function without inspecting the result can pass even when its returned value no longer matches the explanation. Conversely, an assertion about an incidental detail can create maintenance work without protecting a reader-facing promise.

For a negative example, preserve the reason the page presents it. A compile_fail test confirms the expected compilation outcome, but a maintainer should still read the explanation to ensure that it describes the intended lesson. A should_panic example has a different expected runtime outcome. When editing either example, review the attribute, the code and the text as a unit. If one changes without the others, a passing result can still leave the page misleading.

Review coverage when the crate changes

When changing a public function, search for its examples in crate documentation, module documentation and the separate site. Update each reader-facing occurrence or explain why a particular page intentionally shows a different context. Run the native tests after the edit, and inspect the selected tests rather than relying solely on the final exit status. A command can succeed while an ignored or compile-only sample leaves an important behavior untested.

A README included in tested crate documentation can provide valuable coverage at a common entry point. Check the inclusion and the test result in the actual project; a separate README or site page may need its own arrangement. A reader may arrive directly at a page without having followed the earlier tutorial, so verify that its stated prerequisites match the way it is intended to be used. The installation guide helps identify the setup that belongs in a reader journey.

Keep a record for examples that cannot safely or reasonably run in the normal test environment. State the reason, the behavior that remains unchecked and the owner of any separate verification. This makes an intentional exception visible to future maintainers. Revisit it when the API or environment changes instead of allowing a skip to become an unexplained permanent assumption.

Compare a native result with a site scan

The native Rust test and the Markdown scan answer different questions. A Rust doctest can compile and run a documented crate example, including code hidden from the displayed sample. The scan can exercise supported fenced languages on the same site and report a Rust fence as unsupported. Neither result should be used as shorthand for the other. Link the results in a change review so that a reviewer can see both the Rust evidence and the remaining site coverage.

For example, an installation page might contain a shell command followed by a Rust snippet. A supported shell check can reveal whether its documented setup works in the test environment. The Rust snippet still needs its own native check. If those checks use different package sources, record that difference: a passing local crate test does not automatically prove that the package a reader installs contains the same API. Review the Go guide for the same separation of a supported surrounding page and a compiled-language example.

After a failure, reproduce the smallest relevant case with the same crate and edition, note what the reader was told to do, and inspect both visible and hidden code. Change the source that owns the incorrect instruction, rerun the native test, and review the rendered page if the displayed explanation changed. Retain the evidence with the change so the next maintainer understands what the test protects.

Triage failures before editing

Finding Investigation Next action
Rust compilation error Compare the example, crate API and edition used by the test Reproduce and correct the example or its stated context
Assertion fails Compare the promised value with actual behavior Decide whether the code, example or expected value should change
no_run or ignore Determine why execution is absent Record the gap and arrange an appropriate separate check
compile_fail unexpectedly compiles Review the negative example and its intended lesson Update the test and explanation together
unsupported-lang The Rust fence was recognized but skipped by the product Run the native Rust test and retain its result
missing-install-step A supported-language page uses a package without installing it Review the hint and the reader's prerequisites
needs-credentials A supported example requires credentials Record the gap and use a separate authorized check
runtime-error or timeout The failure may require review rather than an automatic docs-bug decision Reproduce with the documented setup and inspect the evidence

A raw failure is a starting point for investigation. A test environment can lack a fixture, use a different package, or supply context the page does not. Preserve the first error and the relevant source location before making changes. Then rerun the affected native test and any supported page scan after the fix.

Checklist for Rust documentation tests

Check Evidence to retain
Inventory crate, module, included README and separate page examples Source locations and the check that reaches each one
Run native documentation tests Command, selected tests and result
Check meaningful results Assertions and the behavior they express
Review edition and fence attributes Intended edition, skips and compile-only cases
Inspect hidden lines Setup supplied to the test and what the reader sees
Show relevant warnings Warning settings and output
Scan supported site examples Planned treatment, findings and skipped Rust fences
Triage and rerun Error, decision, changed source and verification
Review uncovered journeys Separate Markdown, credentials and environment-dependent behavior

What this does not replace

DocsAlive does not run rustc, cargo, cargo test, cargo test --doc or rustdoc --test. Rust examples are recognized but not executed and receive unsupported-lang; a passing report cannot prove they compiled or ran. It also does not render the documentation site or check links. Keep the site build, native Rust tests and human review of the explanation alongside its scan.

For supported Markdown fences, the product runs Python, JavaScript, shell and other supported examples or validates supported data formats. TypeScript support is limited to stripping simple annotations before execution; other TypeScript-only syntax is not judged, and JSX and TSX are not judged. Credential examples are classified rather than run with real keys. The frameworks reference and documentation testing overview describe scope; the Go guide covers the comparable compiled-language boundary.

For a starting point, the free health check accepts a public repository you own or maintain; the team runs the engine on up to 40 of its docs pages and emails the real report within 2 business days; the checkout is deleted after the run. Pricing is Open source $0/month, Team $299/month, Growth $699/month, and Scale from $1,499/month.

For a site using VitePress, see testing VitePress examples. Browse the other guides for language and workflow coverage.

The sources we checked

Source What it covers
rustdoc documentation tests Preprocessing, hidden lines, attributes and warnings
Cargo test Test command and documentation tests
Rust documentation comments Documentation comments and testing
What is rustdoc Rust documentation tooling

FAQ

Does cargo test run documentation tests?

Documentation tests run by default alongside other tests. Inspect the actual output and configuration to establish the examples covered by your run.

What does cargo test --doc check?

It selects documentation tests. A regular doctest must compile and run without panicking; its attributes may instead specify a different outcome or omit execution.

Does a passing Rust fence in the product report prove compilation?

No. Rust fences are recognized and skipped as unsupported-lang. Use rustdoc or Cargo for that evidence, as the Go guide recommends for its own compiled-language boundary.

Why hide a line with #?

A single leading hash can keep setup or an assertion in the test while hiding it from the displayed example. Ensure hidden setup does not conceal a prerequisite readers need.

Does no_run check runtime behavior?

No. It compiles the example but does not run it. Plan a separate execution check when the page promises runtime behavior.

How do I check a value returned by an example?

Use an assertion in a regular doctest. A failing assertion panics and fails the test, making the expected result part of the check.

Do warning display options show every unused warning?

No. Rustdoc says unused warnings remain hidden by default even when output is shown. Its documentation describes how to enable them.

Should separate Markdown pages be tested too?

Yes, if readers rely on them. Identify whether they are included in documentation rustdoc tests; otherwise provide separate coverage instead of assuming the native test reaches them.

Keep reading
Outlined documentation pages with a lime pulse line running out of the stackGuide

Docs Testing: How to Test the Code Samples in Your Docs

Why code examples in documentation break, the ways teams test them (doctest, docs-as-tests, CI runners) and how to run every sample on each release.

Two lenses held over the same documentation page, each bringing a different layer into focusComparison

Vale vs markdownlint: What Each Docs Linter Catches

Vale checks prose style; markdownlint checks Markdown structure. What each catches, sample configs, running both in CI and what neither one tests.

Blueprint of two documentation pages: one with a handwritten test script, one whose code blocks are framed and checkedComparison

Doc Detective vs DocsAlive: Testing the Code in Your Docs

Doc Detective is a free, open-source docs-as-tests framework; DocsAlive is a hosted docs CI for code examples. Features, price, setup and when to use each.

A machine blueprint above a ruled documentation page, with a caliper measuring between themComparison

Promptless Alternative: Promptless vs DocsAlive Compared

Promptless drafts docs updates from what you ship; DocsAlive runs the code examples you've published. Features, pricing, security and when to use each.

A long workbench of outlined testing instruments, each with a small lime light, beside a stack of documentation pagesGuide

Best Free Tools to Test Code Examples in Documentation

Free, open-source tools that run the code examples in your docs: rustdoc, Go examples, doctest, pytest plugins, Sphinx doctest, Doc Detective and byexample.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing SDK Docs Before Every Release: A Release-Gate Guide

Test SDK and client-library docs against the package you ship: build the wheel or npm tarball, install it clean, run every example, and gate the release in CI.

Outlined documentation pages with a lime pulse line running out of the stackGuide

How to Test Quickstarts and Tutorials in Your Docs

Test the onboarding path a new reader follows: run quickstarts in a clean environment, in page order, sort real bugs from credentials and fragments, and wire it into CI.

Outlined documentation pages with a lime pulse line running out of the stackGuide

How to Test CLI Documentation: Commands, Flags and Output

Test the commands a CLI page promises: install in a clean container, run examples in order, compare flags with --help, check exit codes and output, and run it in CI.

Outlined documentation pages with a lime pulse line running out of the stackGuide

How to Test API Reference Docs: Requests, Responses and SDKs

Test API reference pages against the contract they publish: methods, parameters, request and response examples, SDK snippets, status codes and OpenAPI samples.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Docs testing for API-first companies

Keep API quickstarts, SDK snippets and curl examples working across releases.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Docs testing for CLI and developer-tool vendors

Test developer-tool install paths, package managers and command examples across releases.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing README Code Examples: Install, Usage and CI

Keep README install commands and usage examples working with clean environments, output checks and CI.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing Notebooks and Executable Docs: Cells, Kernels and Output

Test notebooks in fresh kernels, check meaningful output and manage dependencies, data and drift in CI.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing Docs in GitHub Actions: Pull Requests and Scheduled Checks

Run documentation example checks in GitHub Actions with practical guidance on schedules, path filters, caching, secrets and reports.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing Code Examples in MkDocs, Docusaurus and Sphinx Sites

Find and test documentation examples in Markdown, MDX and reStructuredText, alongside site builds and link checks.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Python Docs Testing: Doctest, Pytest and Markdown

Test Python documentation with doctest, pytest, Markdown example execution and isolated environments.

Outlined documentation pages with a lime pulse line running out of the stackGuide

JavaScript Docs Testing: Node, TypeScript and Modules

Test Node and TypeScript documentation examples across module formats, package versions and type checks.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing Go documentation examples

Test Go example functions and Markdown snippets against the intended module versions in clean environments.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Sphinx Docs Testing: doctest, code-block and MyST

Test Sphinx documentation examples: what the doctest and linkcheck builders prove, code-block and literalinclude, MyST fences, and what a Markdown scan covers.

Outlined documentation pages with a lime pulse line running out of the stackGuide

ReadMe Docs Testing: CLI, OpenAPI and Code Examples

Test ReadMe documentation examples: docs-as-code and bi-directional sync, what lint and oas:validate prove, Tabs variants and runnable code.

Outlined documentation pages with a lime pulse line running out of the stackGuide

TypeScript Docs Testing: tsc --noEmit and Runtime

Test TypeScript documentation examples: type-check snippets with tsc --noEmit in a consumer project, then run them, and what each check proves.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Docusaurus Docs Testing: Code Blocks, Tabs and MDX

Test Docusaurus documentation examples: builds vs runnable code, code block metadata, Tabs install variants, MDX pages and clean-container runs.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Mintlify Docs Testing: CodeGroup, Tabs and the CLI

Test Mintlify documentation examples: docs.json, MDX pages, CodeGroup and Tabs variants, what mint broken-links and mint validate prove, and clean runs.

Outlined documentation pages with a lime pulse line running out of the stackGuide

MkDocs Docs Testing: Code Examples, Tabs and Snippets

Test MkDocs documentation examples: strict builds, Material tabs, Snippets includes, mkdocstrings pages and clean-container runs.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing Installation Instructions: pip, npm and Containers

Test documented install steps in clean environments: pip and extras, venv, npm install vs npm ci, containers and the first import.

Outlined documentation pages with a lime pulse line running out of the stackGuide

AI SDK Docs Testing: LLM Examples, Keys and Drift

Test AI and LLM SDK documentation examples: requests, responses, streaming, tool calls, credentials, model retirements and CI.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing migration guides and changelog examples

Test before and after examples against the right releases and make migration documentation part of the release gate.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Docs Testing Checklist: Code Examples Before Release

A practical pre-release checklist for testing documentation examples, reviewing gaps and verifying published packages.

Outlined documentation pages with a lime pulse line running out of the stackGuide

The Cost of Broken Code Examples in Documentation

Understand how broken documentation examples create friction in developer adoption and support, and how to reduce it.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing VitePress documentation examples

Test VitePress Markdown examples separately from the site build, including code groups, includes and what a plain Markdown scan covers.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing docs in GitLab CI

Run documentation example checks in GitLab CI jobs, keep site builds separate from execution, and review what a scan covers and skips.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing JSON, TOML and YAML examples in docs

Test JSON, TOML and YAML config examples in documentation: parse, schema and tool checks, honest fence labels, fragments, CI jobs and what a scan covers.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing Java documentation examples

Test Java examples in READMEs, SDK docs and Javadoc: the source launcher, javac, JShell scripts, assertions, @snippet files, CI and what a scan covers.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing PHP documentation examples

Test PHP examples in docs: php -l lint, clean-directory runs, assertions with zend.assertions, Composer scratch projects, PHPUnit, CI and scan coverage.

Outlined documentation pages with a lime pulse line running out of the stackGuide

Testing docs examples that need API keys

Test credential-gated docs examples: honest placeholders, offline stubs and fixtures, live sandbox jobs, CI secrets and fork rules, and how a scan classifies them.

A machine blueprint above a ruled documentation page, with a caliper measuring between themGuide

Documentation Drift: How to Detect It Before Users Do

What documentation drift is, why code examples drift first, and practical ways to detect it: ownership, release checks, link and execution tests.

See which of your code samples still run.

Send us a public repository. Our team runs DocsAlive on its docs and emails you the real report within 2 business days. Free, no signup.