Testing Docstring Examples with doctest
Turn concise Python docstring and documentation examples into executable checks with doctest, testmod, testfile, expected exceptions, and unittest integration.
Intermediate
A useful example in a docstring can do two jobs: explain how a function is meant to behave and let Python check that the example still works. The built-in
doctest module recognizes interactive-console examples, executes them, and compares the displayed result with the expected text. This lesson focuses on that documentation-first testing style;
unittest.TestCase, fixture setup, and mocks already have their own lessons.
Turn examples into executable contracts
Write a small example as if you were using the interactive Python prompt. Start input lines with
>>>, then place the exact expected output on the following line. Keep the example close to the function's docstring so a reader can discover it with
help() and run it as a test. Examples should describe stable behavior that users care about, rather than incidental implementation details.
Output
Ready to run.
The first example places three input/output pairs in
shipping_total()'s docstring.
doctest.testmod() scans the current module for docstrings and runs those examples. A successful non-verbose run is quiet;
verbose=True is helpful while learning because it shows each check and its result. The returned result has a
failed count, so the surrounding script can also make success explicit.
Run docstring examples with testmod
For an ordinary module, the common entry point is
doctest.testmod(). Put it behind
if __name__ == "__main__": when the test should run only when the file is executed directly. You can also ask the standard-library command-line runner to test a file:
python -m doctest -v shipping.py. Use
-v for details. Importing a file for testing executes its top-level code, so keep module imports free of unwanted side effects.
Output
Ready to run.
Doctest examples run in a copy of a module's global namespace for each docstring, which helps prevent one docstring's temporary names from leaking into another. Keep each example understandable on its own and avoid depending on hidden order between examples.
Match returned values, printed output, and exceptions
An expression at the interactive prompt displays its representation: a returned string normally appears with quotes. A function that calls
print() instead produces its printed text without those quotes. The expected output must match the relevant display; confusing
return and
print is a common reason an otherwise correct example fails.
Output
Ready to run.
Doctest can check expected exceptions too. Include the
Traceback (most recent call last): heading, optionally use
... for the traceback stack, and finish with the exception type and message. The traceback stack itself is ignored, but the exception type and detail are compared by default. Avoid depending on full file paths, line numbers, memory addresses, or other output that varies across machines or versions.
Output
Ready to run.
Represent a returned string
Complete the expected display for a function that returns the string `"ready"` when called in the interactive prompt.
def status():
"""Return the current status.
>>> status()
"""
return "ready"
import doctest
result = doctest.testmod()
assert result.failed == 0
Test examples in a documentation text file
Interactive examples do not have to live in a Python source file.
doctest.testfile() can check console examples in a plain-text tutorial or README. This is useful when documentation contains short, copyable snippets. Be explicit about file encoding, and pass
module_relative=False when supplying a direct filesystem path rather than a path relative to a module.
Output
Ready to run.
For a project, a command such as
python -m doctest -v guide.txt runs the examples in a text file. Doctest's expected output format is intentionally simple: it is not a general parser for every shell transcript, traceback, or formatting convention. If an example needs setup that is too complex to understand, use a dedicated test with explicit setup rather than hiding that complexity in the documentation.
Choose the text-file API
Complete the call that checks Python prompt examples in a text file at a known filesystem path.
import doctest
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "guide.txt"
path.write_text(">>> 2 + 2\n4\n", encoding="utf-8")
result = doctest.(str(path), module_relative=False)
assert result.failed == 0
Integrate doctest with unittest when useful
A project can keep examples in docstrings and still include them in a broader
unittest run.
doctest.DocTestSuite() builds a test suite from a module's docstring examples. This is an integration point, not a replacement for
unittest.TestCase: use ordinary unit tests for complex setup, multiple assertions, detailed diagnostics, or behavior that is awkward to express as a short console transcript.
Output
Ready to run.
Build a suite from a module
Choose the `doctest` helper that returns a `unittest` suite from examples in a module.
import doctest
import io
import sys
import unittest
def sample():
"""A tiny example.
>>> sample()
'done'
"""
return "done"
suite = doctest.(sys.modules[__name__])
result = unittest.TextTestRunner(stream=io.StringIO()).run(suite)
assert result.wasSuccessful()
Know when doctest is not enough
Doctest is strongest when a concise example is itself useful documentation: a function's normal inputs, return values, and a small number of stable edge cases. It can become brittle when output contains unstable representations, depends on external state, or requires a long setup. Don't loosen output matching just to make a fragile example pass; simplify the example or use a more suitable unit test. Keep pure behavior real, and isolate external collaborators only when that boundary is what the test needs to control.
Keep an example stable
Which expected output is the safest choice for a beginner-facing doctest?
def describe_count(count):
"""Return a short description.
>>> print(describe_count(3))
"""
return f"{count} items"
import doctest
result = doctest.testmod()
assert result.failed == 0
Check expected exceptions
Complete the exception line that records the type and stable message raised by this doctest.
def parse_age(value):
"""Reject negative ages.
>>> parse_age(-1)
Traceback (most recent call last):
...
"""
if value < 0:
raise ValueError("age must be non-negative")
return value
import doctest
result = doctest.testmod()
assert result.failed == 0
Run a file with detailed feedback
Which value makes `doctest.testmod()` print details for each attempted example?
import doctest
def ping():
"""Return a fixed response.
>>> ping()
'pong'
"""
return "pong"
result = doctest.testmod(verbose=)
assert result.attempted == 1
assert result.failed == 0
A practical checklist
- Put concise, runnable interactive examples in docstrings when they clarify how a function should behave.
- Use doctest.testmod() for module docstrings and doctest.testfile() for prompt examples in text documentation.
- Match returned-value representations, printed output, and expected exceptions accurately; avoid unstable output.
- Use DocTestSuite() to include module examples in unittest when that fits the project, not to replace complex unit tests.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.