pytest-codeblock
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. The only requirement here is that your code blocks shall have a name starting withtest_. 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.pyhooks.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. All your .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
Note
Note that :name: value has a test_ prefix.
Filename: README.rst
.. code-block:: python
:name: test_basic_example
import math
result = math.pow(3, 2)
assert result == 9
literalinclude directive example
Note
Note that :name: value has a test_ prefix.
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.
Note
Note that name value has a test_ prefix.
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.
Project documentation
Contents: