pytest-codeblock - A pytest plugin for testing code examples in Markdown and reStructuredText files

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

social