Examples as Executable Documentation
Example functions with Output comments in godoc.
Summary
Go examples are test functions that pkg.go.dev renders as documentation.
When you add an // Output: comment, go test compares stdout and fails if the example drifts.
They complement table-driven tests by showing the public API the way callers use it.
Recipe
Quick-reference recipe card - copy-paste ready.
func ExampleAdd() {
fmt.Println(Add(2, 3))
// Output: 5
}When to reach for this:
- A package exports a function consumers copy from docs
- You want CI to fail when documented output changes
- Type-specific usage belongs on the type's doc page (
ExampleUser_Marshal) - README snippets should match godoc exactly
- You need compile-only examples without asserting output order
Working Example
package greet
import "fmt"
func Hello(name string) string {
if name == "" {
return "Hello, world"
}
return "Hello, " + name
}
func ExampleHello() {
fmt.Println(Hello("Ada"))
// Output: Hello, Ada
}
func ExampleHello_empty() {
fmt.Println(Hello(""))
// Output: Hello, world
}What this demonstrates:
ExampleHellodocuments the common path- Suffix
_emptyadds a second documented scenario go testverifies printed output matches the comment- Examples live in
_test.gowith production code in the same module
Deep Dive
How It Works
- Functions named
ExampleorExampleXxxare collected bygo test. - The optional suffix after
_disambiguates multiple examples (ExampleSort_reverse). ExampleDoc(no suffix) can document a whole package when paired withpackage greetin the file.// Output:compares trimmed stdout; use// Output:\nfor multiline expected text.
Naming and godoc placement
| Name pattern | Appears on |
|---|---|
ExampleFoo | Function Foo |
ExampleBar_qux | Function Bar (scenario qux) |
ExampleMyType | Type MyType |
ExampleMyType_method | Method on MyType |
Go Notes
func ExampleShuffle() {
// shuffle output - compile only, no Output comment
rand.Shuffle(3, func(i, j int) { /* ... */ })
}Omit // Output: when output is nondeterministic; the example still must compile.
Gotchas
- Missing or stale Output comment - example fails or docs lie. Fix: Run
go testafter every doc change; update the comment when behavior changes. - Examples importing internal packages - external readers cannot copy them. Fix: Keep examples on exported symbols in
package fooorfoo_test. - Side effects in examples - writing files or using random without seed fails CI. Fix: Use deterministic inputs; mock time when needed.
- fmt.Println formatting -
Outputis exact string match. Fix: Match spacing; preferfmt.Printfwith explicit format when teaching APIs. - Heavy setup in examples - godoc readers see noise. Fix: Show the minimal call pattern; link to full tests for edge cases.
- Example in wrong file package -
package foo_testexamples cannot show unexported helpers. Fix: Usepackage foofor internal mechanics only when exported API allows.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| README code blocks | Narrative tutorials | You need CI verification |
| Table-driven tests | Exhaustive cases | Teaching one happy path |
go doc comments only | Trivial one-liners | Output shape matters |
| Playground on pkg.go.dev | Shareable snippets | Repo must build without network |
FAQs
Do examples run in CI automatically?
Yes - go test executes them with other tests in the package.
Failed Output checks fail the build.
Can examples return values?
No - examples must be void functions.
Use fmt.Print to demonstrate results.
How do I document multiple return values?
Print each value or a formatted struct with fmt.Printf("%#v", v).
What is ExampleMain?
Rare - documents package initialization.
Most packages use ExampleFunc instead.
Can I use testify in examples?
Avoid it - examples should use stdlib only so godoc stays dependency-free for readers.
How do I test HTTP handlers in examples?
Use httptest and print the recorder body - keep it short.
Long flows belong in normal tests.
Does Output support regex?
No - exact match only.
For unordered map output, print sorted keys or skip Output.
Where do example files live?
example_test.go or foo_test.go beside production code.
go test picks them up automatically.
Can examples be in internal packages?
They run locally but internal paths do not appear on public pkg.go.dev the same way.
Prefer examples on exported module APIs.
How do I update Output after intentional change?
Run the example with go test -run ExampleHello -v, copy actual stdout into the comment.
Are examples benchmarks?
No - benchmarks use BenchmarkXxx(*testing.B).
Examples measure documentation, not performance.
Can I hide examples from godoc?
Unexported example names are not shown.
There is no //go:example off - delete or rename if not ready.
Related
- Go Testing Basics - external test packages
- Go Testing Culture: Simple, Fast, Table-Driven - docs culture
- Table-Driven Tests & Subtests - exhaustive cases
- testify, httptest & Test Doubles - handler testing
- Testing Best Practices - what to document vs test
Stack versions: This page was written for Go 1.26.x (Green Tea GC default, go fix modernizers - verify patch at build), chi (latest - verify at build), gin (latest - verify at build), echo (latest - verify at build), google.golang.org/grpc (latest - verify at build), sigs.k8s.io/controller-runtime (latest - verify at build), kubebuilder (latest - verify at build), tinygo (latest - verify board targets at build), wazero (latest - verify at build), and golangci-lint (latest - verify linter set at build).