Python doctest finds text that resembles interactive Python sessions inside docstrings or documentation files, executes each command, and compares actual output with the documented output. It turns examples into executable documentation and helps keep tutorials, help text, and API snippets synchronized with the code.
The module works best for small, deterministic, readable examples. It is not a replacement for a complete test suite, especially for complex state, networking, concurrency, elaborate fixtures, or behavior that requires detailed assertions.
Write the first doctest
A docstring may include >>> prompts followed by expected output.
def double(value):
"""Return twice the input.
>>> double(4)
8
>>> double(-3)
-6
"""
return value * 2The text follows interactive-session conventions. Expected output starts immediately after the command and ends at another prompt or a blank line.
Run examples with testmod
if __name__ == "__main__":
import doctest
doctest.testmod()Running the file produces no output when every example passes. Use verbose mode to see each attempted example:
python module.py -vIn automated builds, check the exit behavior or integrate doctests with unittest so configuration mistakes do not look like successful runs.
Use the command line
python -m doctest module.py
python -m doctest -v module.pyPassing a package member as a standalone file may break relative imports. For package code, importing it through the proper package context is often more reliable.
Test documentation files
testfile() reads interactive examples from a text file such as reStructuredText or Markdown.
import doctest
result = doctest.testfile(
"guide.txt",
module_relative=False,
)
print(result)The entire file is treated like one large docstring, allowing tutorial examples to be verified without placing all of them in application source.
Understand execution context
Each discovered docstring normally receives a shallow copy of the module globals. Examples in the same docstring share names; examples from different docstrings normally do not.
def state_example():
"""
>>> values = [1, 2]
>>> values.append(3)
>>> values
[1, 2, 3]
"""A shallow copy still shares referenced mutable objects. Avoid real global state and clean up files, environment variables, and connections after tests.
Provide explicit globals
globs and extraglobs prepare names for examples.
doctest.testfile(
"examples.txt",
globs={"Client": Client},
extraglobs={"config": test_config},
module_relative=False,
)Do not inject production credentials, live database sessions, or irreversible resources. Use fakes, temporary directories, and test configurations.
Document exceptions
An example may include the expected traceback. Intermediate stack lines are normally ignored, while the exception type and detail are compared.
def divide(a, b):
"""
>>> divide(10, 0)
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
"""
return a / bIf messages vary across versions, IGNORE_EXCEPTION_DETAIL can focus on the exception type. Use it only when the message is not part of the public contract.
Normalize whitespace
NORMALIZE_WHITESPACE treats whitespace sequences as equivalent.
>>> print(list(range(10))) # doctest: +NORMALIZE_WHITESPACE
[0, 1, 2, 3, 4,
5, 6, 7, 8, 9]Apply the directive only where wrapping is irrelevant. Global normalization can hide meaningful formatting regressions.
Use ELLIPSIS carefully
ELLIPSIS allows ... to match arbitrary output.
>>> object_value
<MyObject id=...> # doctest: +ELLIPSISKeep stable prefixes and suffixes around the marker. Broad ellipses can accept incorrect output just as a greedy regular expression can.
Represent blank lines
A blank line ends expected output. To require an actual blank line, write <BLANKLINE>.
>>> print("first\n\nthird")
first
<BLANKLINE>
thirdThis rule is a common source of failures in copied multiline output.
Avoid nondeterministic ordering
Do not compare sets or mappings whose display order is not part of the API.
>>> sorted(get_tags())
['api', 'python', 'test']Format floating-point values explicitly. Avoid timestamps, memory addresses, random UUIDs, temporary paths, and platform-dependent messages unless normalized.
Add hidden examples with __test__
A module-level __test__ mapping adds doctests that do not need to appear in the main help text.
__test__ = {
"extra_cases": """
>>> double(0)
0
""",
}Values may be strings, functions, or classes. Their docstrings are searched recursively.
Which objects are searched?
testmod() examines the module docstring, functions, classes, methods, nested class members, and objects exposed through __test__. Objects imported from other modules are not searched automatically.
The Python pydoc guide explains how documentation is displayed. To list classes and functions without importing a module, see Python pyclbr.
Integrate with unittest
DocTestSuite() turns a module’s examples into a unittest suite.
import doctest
import unittest
import my_module
def load_tests(loader, tests, pattern):
tests.addTests(doctest.DocTestSuite(my_module))
return tests
if __name__ == "__main__":
unittest.main()DocFileSuite() performs the same conversion for text files. This makes discovery, reporting, and execution consistent with normal unit tests.
Set up and clean up resources
The suite APIs accept setUp and tearDown callbacks.
def set_up(test):
test.globs["repository"] = TemporaryRepository()
def tear_down(test):
test.globs["repository"].close()
suite = doctest.DocTestSuite(
my_module,
setUp=set_up,
tearDown=tear_down,
)Cleanup must occur even after failures. Prefer tempfile, mocks, and in-memory resources.
Fail fast and improve reports
The command-line -f option enables FAIL_FAST. Other flags show unified, context, or intraline differences.
python -m doctest -v -f guide.txtFail-fast is convenient while debugging. A full CI run may be more valuable because it reports all stale examples at once.
Skip examples deliberately
>>> open_browser() # doctest: +SKIPSKIP is appropriate for purely illustrative commands or unavailable services. Review skips regularly because they can hide broken documentation.
Parse examples programmatically
DocTestParser extracts Example objects from text.
from doctest import DocTestParser
text = """
>>> 2 + 2
4
"""
examples = DocTestParser().get_examples(text)
print(examples[0].source, examples[0].want)DocTestFinder, DocTestRunner, and OutputChecker enable custom integrations. Use the basic API unless you need specialized discovery or comparison rules.
Security
Doctest executes the examples it discovers. Never run user-submitted documentation, unknown packages, or untrusted repositories in the main application process.
Use a restricted process or container with a timeout, memory and CPU limits, no production credentials, a temporary filesystem, and network restrictions. Importing the tested module can itself execute top-level code before examples run.
Tracebacks and diagnostics
The Python traceback guide explains exception formatting. In doctests, include only stable exception details and omit file paths and line numbers unless they add instructional value.
Introspection and documentation
Python inspect can help documentation tools retrieve signatures and docstrings before building suites. Remember that live-object introspection normally requires importing the target code.
When doctest is not the right tool
- Long workflows with complex fixtures.
- Large or unstable output.
- Concurrency and timing tests.
- Real network and database integration.
- Property testing across many values.
- Critical rules that need detailed assertions.
Use unittest, pytest, or specialized frameworks for these cases and keep doctests focused on public examples.
Recommended practices
- Keep examples short and deterministic.
- Test public behavior instead of internals.
- Sort collections before displaying them.
- Format floating-point output explicitly.
- Use directives locally.
- Avoid excessive ellipsis matching.
- Run documentation tests in CI.
- Isolate untrusted documentation.
Conclusion
Python doctest keeps examples synchronized with implementation and turns documentation into executable tests. It is excellent for small APIs, tutorials, and readable regressions when outputs are stable.
Consult the official doctest documentation and the Python unittest documentation.







