Framework
- Pytest
Development Status
- 4 - Beta
Intended Audience
- Developers
Operating System
- OS Independent
Programming Language
- Python :: 3.10
- Python :: 3.11
- Python :: 3.12
- Python :: 3.13
- Python :: 3.14
- Python
Topic
- Software Development :: Testing
- Software Development
Test your documentation code blocks.
pytest-codeblock is a Pytest plugin that discovers Python code examples in your reStructuredText and Markdown documentation files and runs them as part of your test suite. This ensures your docs stay correct and up-to-date.
Features
reStructuredText and Markdown support: Automatically find and test code blocks in reStructuredText (.rst) and Markdown (.md) files. Async code snippets are supported as well.
Grouping: Split a single example across multiple code blocks; the plugin concatenates them into one test.
Pytest markers support: Add existing or custom pytest markers to the code blocks and hook into the tests life-cycle using conftest.py.
Pytest fixtures support: Request existing or custom pytest fixtures for the code blocks.
Prerequisites
Documentation
Documentation is available on Read the Docs.
For reStructuredText, see a dedicated reStructuredText docs.
For Markdown, see a dedicated Markdown docs.
Both reStructuredText docs and Markdown docs have extensive documentation on pytest markers and corresponding conftest.py hooks.
For guidelines on contributing check the Contributor guidelines.
Installation
Install with pip:
pip install pytest-codeblock
Or install with uv:
uv pip install pytest-codeblock
Configuration
For most use cases, no configuration needed.
By default, all code blocks with a name starting with test_ will be collected and executed as tests. This allows you to have both test and non-test code blocks in your documentation, giving you flexibility in how you structure your examples.
However, if you want to test all code blocks, you can set test_nameless_codeblocks to true in your pyproject.toml:
Filename: pyproject.toml
[tool.pytest-codeblock]
test_nameless_codeblocks = true
If you still want to skip some code blocks, you can use built-in or custom pytest markers.
See the dedicated reStructuredText docs and Markdown docs to learn more about pytestmark directive.
Note, that nameless code blocks have limitations when it comes to grouping.
By default, all code .rst and .md files shall be picked automatically.
However, if you need to add another file extension or use or another language identifier for python in codeblock, you could configure that.
See the following example of pyproject.toml configuration:
Filename: pyproject.toml
[tool.pytest-codeblock]
rst_user_codeblocks = ["c_py"]
rst_user_extensions = [".rst.txt"]
md_user_codeblocks = ["c_py"]
md_user_extensions = [".md.txt"]
See customisation docs for more.
Usage
reStructruredText usage
Any code directive, such as .. code-block:: python, .. code:: python, or literal blocks with a preceding .. codeblock-name: <name>, will be collected and executed automatically by pytest.
code-block directive example
Filename: README.rst
.. code-block:: python
:name: test_basic_example
import math
result = math.pow(3, 2)
assert result == 9
literalinclude directive example
Filename: README.rst
.. literalinclude:: examples/python/basic_example.py
:name: test_li_basic_example
See a dedicated reStructuredText docs for more.
Markdown usage
Any fenced code block with a recognized Python language tag (e.g., python, py) will be collected and executed automatically by pytest.
Filename: README.md
```python name=test_basic_example
import math
result = math.pow(3, 2)
assert result == 9
```
See a dedicated Markdown docs for more.
Tests
Run the tests with pytest:
pytest
Troubleshooting
If something doesn’t work, try to add this to your pyproject.toml:
Filename: pyproject.toml
[tool.pytest.ini_options]
testpaths = [
"**/*.rst",
"**/*.md",
]
Writing documentation
Keep the following hierarchy.
=====
title
=====
header
======
sub-header
----------
sub-sub-header
~~~~~~~~~~~~~~
sub-sub-sub-header
^^^^^^^^^^^^^^^^^^
sub-sub-sub-sub-header
++++++++++++++++++++++
sub-sub-sub-sub-sub-header
**************************
License
MIT
Support
For security issues contact me at the e-mail given in the Author section.
For overall issues, go to GitHub.