Skip to main content

mktestdocs

Run pytest against markdown files/docstrings.

Installation

pip install mktestdocs

Usage

Let's say that you're using mkdocs for your documentation. Then you're writing down markdown to explain how your Python packages work. It'd be a shame if a codeblock had an error in it, so it'd be great if you could run your unit tests against them.

This package allows you to do just that. Here's an example:

import pathlib
import pytest

from mktestdocs import check_md_file

# Note the use of `str`, makes for pretty output
@pytest.mark.parametrize('fpath', pathlib.Path("docs").glob("**/*.md"), ids=str)
def test_files_good(fpath):
    check_md_file(fpath=fpath)

This will take any codeblock that starts with ```python and run it, checking for any errors that might happen. This means that if your docs contain asserts, that you get some unit-tests for free!

Multiple Code Blocks

Let's suppose that you have the following markdown file:

This is a code block

```python
from operator import add
a = 1
b = 2
```

This code-block should run fine.

```python
assert add(1, 2) == 3
```

Then in this case the second code-block depends on the first code-block. The standard settings of check_md_file assume that each code-block needs to run independently. If you'd like to test markdown files with these sequential code-blocks be sure to set memory=True.

import pathlib

from mktestdocs import check_md_file

fpath = pathlib.Path("docs") / "multiple-code-blocks.md"

try:
    # Assume that cell-blocks are independent.
    check_md_file(fpath=fpath)
except NameError:
    # But they weren't
    pass

# Assumes that cell-blocks depend on each other.
check_md_file(fpath=fpath, memory=True)

Markdown in Docstrings

You might also have docstrings written in markdown. Those can be easily checked as well.

# I'm assuming that we've got a library called dinosaur
from dinosaur import roar, super_roar

import pytest
from mktestdocs import check_docstring

# Note the use of `__name__`, makes for pretty output
@pytest.mark.parametrize('func', [roar, super_roar], ids=lambda d: d.__name__)
def test_docstring(func):
    check_docstring(obj=func)

There's even some utilities for grab all the docstrings from classes that you've defined.

# I'm assuming that we've got a library called dinosaur
from dinosaur import Dinosaur

import pytest
from mktestdocs import check_docstring, get_codeblock_members

# This retrieves all methods/properties that have a docstring.
members = get_codeblock_members(Dinosaur)

# Note the use of `__qualname__`, makes for pretty output
@pytest.mark.parametrize("obj", members, ids=lambda d: d.__qualname__)
def test_member(obj):
    check_docstring(obj)

When you run these commands via pytest --verbose you should see informative test info being run.

If you're wondering why you'd want to write markdown in a docstring feel free to check out mkdocstrings.

Bash Support

Be default, bash code blocks are also supported. A markdown file that contains both python and bash code blocks can have each executed separately.

This will print the python version to the terminal

```bash
python --version
```

This will print the exact same version string

```python
import sys

print(f"Python {sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}")
```

This markdown could be fully tested like this

import pathlib

from mktestdocs import check_md_file

fpath = pathlib.Path("docs") / "bash-support.md"

check_md_file(fpath=fpath, lang="python")
check_md_file(fpath=fpath, lang="bash")

Additional Language Support

You can add support for languages other than python and bash by first registering a new executor for that language. The register_executor function takes a tag to specify the code block type supported, and a function that will be passed any code blocks found in markdown files.

For example if you have a markdown file like this

This is an example REST response

```json
{"body": {"results": ["spam", "eggs"]}, "errors": []}
```

You could create a json validator that tested the example was always valid json like this

import json
import pathlib

from mktestdocs import check_md_file, register_executor

def parse_json(json_text):
    json.loads(json_text)

register_executor("json", parse_json)

check_md_file(fpath=pathlib.Path("docs") / "additional-language-support.md", lang="json")

Metadata

Release files for mktestdocs 0.2.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mktestdocs 0.2.5
File Size Uploaded
mktestdocs-0.2.5.tar.gz 10.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mktestdocs 0.2.5
File Interpreter ABI Platform
mktestdocs-0.2.5-py3-none-any.whl Python 3 none any Details

Total release size: 19.6 kB

Release files / mktestdocs-0.2.5.tar.gz

Download URL mktestdocs-0.2.5.tar.gz
Size 10.5 kB
Tags Source
SHA-256 checksum
How to use checksums
7935d4e665b34b690cdf14749abb842723652485f67af12dce51099bcb98e105
BLAKE2b-256 checksum
How to use checksums
fd04aced274f9ea76dfdb7a36c1b729863ebbf61e94b60a0d1eefa2556a61df5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.13

Release files / mktestdocs-0.2.5-py3-none-any.whl

Download URL mktestdocs-0.2.5-py3-none-any.whl
Size 9.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2b20d2387b2025597f3129773edef16d09b08b1b6d31da6cc51af5b693c10430
BLAKE2b-256 checksum
How to use checksums
4feb3686be82dfeb12eb968f002254464e282722e4ac52c465c2998764583f34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.13

Release history Release notifications | RSS feed

This release

0.2.5 This release

2 release files

0.2.4

1 release file

0.2.3

2 release files

0.2.2

1 release file

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page