Skip to main content

Run markdown code fences through pytest

Project description

Pytest Markdown Docs

A plugin for pytest that uses markdown code snippets from markdown files and docstrings as tests.

Detects Python code fences (triple backtick escaped blocks) in markdown files as well as inline Python docstrings (similar to doctests) and runs them as tests.

Python file example:

# mymodule.py
class Foo:
    def bar(self):
        """Bar the foo

        This is a sample docstring for the bar method

        Usage:
        ```python
        import mymodule
        result = mymodule.Foo().bar()
        assert result == "hello"
        ```
        """
        return "hello"

Markdown file examples:

# Title

Lorem ipsum yada yada yada

```python
import mymodule
result = mymodule.Foo().bar()
assert result == "hello"
```

Usage

First, make sure to install the plugin, e.g. pip install pytest-markdown-docs

To enable markdown python tests, pass the --markdown-docs flag to pytest:

pytest --markdown-docs

You can also use the markdown-docs flag to filter only markdown-docs tests:

pytest --markdown-docs -m markdown-docs

Detection conditions

Fence blocks (```) starting with the python, python3 or py language definitions are detected as tests in:

  • Python (.py) files, within docstrings of classes and functions
  • .md, .mdx and .svx files

Skipping tests

To exclude a Python code fence from testing, add a notest info string to the code fence, e.g:

```python notest
print("this will not be run")
```

Code block dependencies

Sometimes you might wish to run code blocks that depend on entities to already be declared in the scope of the code, without explicitly declaring them. There are currently two ways you can do this with pytest-markdown:

Injecting global/local variables

If you have some common imports or other common variables that you want to make use of in snippets, you can add them by creating a pytest_markdown_docs_globals hook in your conftest.py:

def pytest_markdown_docs_globals():
    import math
    return {"math": math, "myvar": "hello"}

With this conftest, you would be able to run the following markdown snippet as a test, without causing an error:

```python
print(myvar, math.pi)
```

Fixtures

You can use both autouse=True pytest fixtures in a conftest.py or named fixtures with your markdown tests. To specify named fixtures, add fixture:<name> markers to the code fence info string, e.g.,

```python fixture:capsys
print("hello")
captured = capsys.readouterr()
assert captured.out == "hello\n"
```

As you can see above, the fixture value will be injected as a global. For autouse=True fixtures, the value is only injected as a global if it's explicitly added using a fixture:<name> marker.

Depending on previous snippets

If you have multiple snippets following each other and want to keep the side effects from the previous snippets, you can do so by adding the continuation info string to your code fence:

```python
a = "hello"
```

```python continuation
assert a + " world" == "hello world"
```

Testing of this plugin

You can test this module itself (sadly not using markdown tests at the moment) using pytest:

> poetry run pytest

Or for fun, you can use this plugin to include testing of the validity of snippets in this README.md file:

> poetry run pytest --markdown-docs

Known issues

  • Only tested with pytest 6.2.5. There seem to be some minor issue with pytest >7 due to changes of some internal functions in pytest, but that should be relatively easy to fix. Contributions are welcome :)
  • Code for docstring-inlined test discovery can probably be done better (similar to how doctest does it). Currently, seems to sometimes traverse into Python's standard library which isn't great...

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

pytest-markdown-docs-0.2.0.tar.gz (5.7 kB view details)

Uploaded Source

Built Distribution

pytest_markdown_docs-0.2.0-py3-none-any.whl (6.8 kB view details)

Uploaded Python 3

File details

Details for the file pytest-markdown-docs-0.2.0.tar.gz.

File metadata

  • Download URL: pytest-markdown-docs-0.2.0.tar.gz
  • Upload date:
  • Size: 5.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.8.10 Linux/5.13.0-40-generic

File hashes

Hashes for pytest-markdown-docs-0.2.0.tar.gz
Algorithm Hash digest
SHA256 9c3386c6e1aa55a7952faa27960cf6b84c1486f7fdc76e156246ba1392829cb1
MD5 71f9bda80a60526987f8b779e1865cab
BLAKE2b-256 3a1f163ad431b5b45d54d50212f5a99440422e184aeba66eea593d6ca6ebd4fa

See more details on using hashes here.

File details

Details for the file pytest_markdown_docs-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_markdown_docs-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 80c578caa4e7000a4332aa2ec4156f77b8cecbb676f88943127fbc9841af85da
MD5 40705f40144c44cd1906f3b288a4b628
BLAKE2b-256 81749d26dbeef4dd0a6bfc6c676ec74ccb9fa2b787be741ea18d598fabb2b2d8

See more details on using hashes here.

Supported by

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