I wrote a small pytest plugin that tests code blocks in your docs.
https://github.com/barseghyanartur/pytest-codeblock
What My Project Does
pytest-codeblock is a minimal pytest plugin that finds Python code examples in your .rst and .md files and runs them as regular pytest tests. No dependencies beyond pytest itself (plus tomli on Python 3.10).
It handles:
- reStructuredText and Markdown — .. code-block:: python, .. code:: python, .. literalinclude::, literal blocks, and fenced ```python blocks
- Grouping — split one logical example across several blocks using .. continue: or <!-- continue: --> and they run as a single test, or as cumulative incremental steps if each continuation has its own name
- pytest markers and fixtures — .. pytestmark: django_db, <!-- pytestmark: skip -->, fixture injection via .. pytestfixture: tmp_path; custom fixtures from conftest.py work too
- ``pytestrun`` marker — run full pytest-style suites (test classes, fixtures, parametrize, setup/teardown) inside a single doc block
- Async support — top-level await is automatically wrapped, no config needed
- Nameless code blocks — opt-in via pyproject.toml; off by default, only test_*-named blocks run unless you enable it
- Custom languages and extensions — configurable if your docs use non-standard identifiers
Feature comparison
| Feature | pytest-codeblock | Sybil | phmdoctest | pytest-codeblocks | doctest |
|---|---|---|---|---|---|
| RST support | ✅ | ✅ | ❌ | ❌ | ✅ |
| Markdown support | ✅ | ✅ | ✅ | ✅ | ❌ |
| Both RST + MD | ✅ | ✅ | ❌ | ❌ | ❌ |
| Native pytest collector | ✅ | ✅ | ❌ | ✅ | ✅ |
| Fixture injection in docs | ✅ | ⚠️ conftest only | ❌ | ❌ | ❌ |
| pytest markers in docs | ✅ | ⚠️ conftest only | ❌ | ❌ | ❌ |
| Block grouping / continuation | ✅ | ✅ | ❌ | ❌ | ❌ |
| Incremental grouping | ✅ | ❌ | ❌ | ❌ | ❌ |
| Async support | ✅ | ⚠️ manual | ❌ | ❌ | ❌ |
| Test classes in doc blocks | ✅ (pytestrun) | ❌ | ❌ | ❌ | ❌ |
| literalinclude support | ✅ | ❌ | ❌ | ❌ | ❌ |
| Nameless block testing | ✅ opt-in | ❌ | ✅ | ✅ | ❌ |
| Zero config to start | ✅ | ❌ | ✅ | ✅ | ✅ |
| No generated files on disk | ✅ | ✅ | ❌ | ✅ | ✅ |
| Zero extra dependencies | ✅ | ❌ | ❌ | ✅ | ✅ |
⚠️ = supported but requires extra wiring outside the doc file
Zero config to start. Install it, run pytest. Any block named test_* becomes a test.
pip install pytest-codeblock
reStructuredText:
.. code-block:: python :name: test_basic_example import math result = math.pow(3, 2) assert result == 9
Markdown:
```python name=test_basic_example import math result = math.pow(3, 2) assert result == 9 ```
Target Audience
Library authors and anyone who has shipped broken doc examples and only found out from a user bug report. If you're already running pytest, the cost to add doc block testing is close to zero.
Comparison
- vs. doctest: doctest is built for REPL-style >>> examples. It works fine for trivial cases but gets awkward fast — multiline logic, fixtures, and async are all painful. pytest-codeblock lets you write plain Python with assert statements, so your examples look like real code rather than a terminal session.
- vs. Sybil: Sybil is the most capable alternative and worth considering for complex setups. The tradeoff is configuration overhead: fixtures and regions need manual wiring in conftest.py. pytest-codeblock keeps fixture requests in the doc file itself (.. pytestfixture: tmp_path) and works with existing conftest.py fixtures without extra setup. If Sybil's power is more than you need, pytest-codeblock is lighter.
- vs. phmdoctest: phmdoctest transpiles Markdown into .py files on disk and runs those. pytest-codeblock is a native pytest collector — no generated files, nothing to add to .gitignore, no intermediate artifacts.
- vs. pytest-codeblocks (plural): Similar name, different scope. pytest-codeblock adds fixture injection, grouping, async wrapping, and the pytestrun marker for full test-class support inside doc blocks.
The plugin is in beta. It's been used in a few projects for about a year and the core behavior is stable, but edge cases and feedback are welcome.
Documentation: https://pytest-codeblock.readthedocs.io/en/latest/
Repository: https://github.com/barseghyanartur/pytest-codeblock
Originally published as GitHub Gist #c48b645466bbd5d071e82588364f8123