Skip to main content

A tool for testing markdown documentation

Project description

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")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mktestdocs-0.2.5.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mktestdocs-0.2.5-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file mktestdocs-0.2.5.tar.gz.

File metadata

  • Download URL: mktestdocs-0.2.5.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.13

File hashes

Hashes for mktestdocs-0.2.5.tar.gz
Algorithm Hash digest
SHA256 7935d4e665b34b690cdf14749abb842723652485f67af12dce51099bcb98e105
MD5 ff2aad21ad3456c8082ae295da59454b
BLAKE2b-256 fd04aced274f9ea76dfdb7a36c1b729863ebbf61e94b60a0d1eefa2556a61df5

See more details on using hashes here.

File details

Details for the file mktestdocs-0.2.5-py3-none-any.whl.

File metadata

  • Download URL: mktestdocs-0.2.5-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.7.13

File hashes

Hashes for mktestdocs-0.2.5-py3-none-any.whl
Algorithm Hash digest
SHA256 2b20d2387b2025597f3129773edef16d09b08b1b6d31da6cc51af5b693c10430
MD5 9151b2798e4bd36fbdaa6a998ddd22b9
BLAKE2b-256 4feb3686be82dfeb12eb968f002254464e282722e4ac52c465c2998764583f34

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page