pytest plugin#

Note

This plugin disables pytest’s standard doctest plugin.

The pytest plugin is built on top of the Doctest w/ docutils module, which is in turn compatible with doctest.

Using fixtures#

Normal pytest convention apply, a visible conftest.py must be available for the file being tested.

This requires a understanding of confest.py - in the same way pytest’s vanilla doctest plugin does.

You know your project’s package structure best, the follow just serve as examples of new places conftest.py will be needed:

Example: Root-level README#

In other words, if you want to test a project’s README.md in the project root, a conftest.py would be needed at the root-level. This also has the benefit of reducing duplication:

conftest.py
    # content of conftest.py
    import pytest

    @pytest.fixture
    def username():
        return 'username'

README.rst
    Our project
    -----------

    .. doctest::

        # content of tests/test_something.py
        def test_username(username):
            assert username == 'username'

Now you can do:

$ pytest README.rst

Examples: docs/#

Let’s assume .md and .rst files in docs/, this means you need to import conftest.py

docs/
	conftest.py
		# import conftest of project
		import pytest

		@pytest.fixture
		def username():
			return 'username'

	usage.rst
		Our project
		-----------

		.. doctest::

			# content of tests/test_something.py
			def test_username(username):
				assert username == 'username'

Now you can do:

$ pytest docs/

File support#

reStructuredText (.rst)#

$ pytest README.rst
$ pytest docs/

Markdown (.md)#

If you install myst-parser, doctest will run on .md files.

$ pytest README.md
$ pytest docs/

Scanning python files#

You can retain pytest’s standard doctest plugin of running doctests in .py by passing --doctest-docutils-modules:

$ py.test src/ --doctest-docutils-modules

You can disable it via --no-doctest-docutils-modules:

$ py.test src/ --no-doctest-docutils-modules

Case examples#

API#

pytest_doctest_docutils

pytest plugin for doctest w/ reStructuredText and markdown

class pytest_doctest_docutils.DocTestDocutilsFile(fspath=None, path_or_parent=None, path=None, name=None, parent=None, config=None, session=None, nodeid=None)[source]#

Bases: Module

collect()[source]#

Return a list of children (items and collectors) for this collection node.

Return type:

Iterable[DoctestItem]

config: Config#

The pytest config object.

name#

A unique name within the scope of the parent node.

parent#

The parent collector node.

path: Path#

Filesystem path where this node was collected from (can be None).

session#

The pytest session this node is part of.

class pytest_doctest_docutils.DocutilsDocTestRunner(checker=None, verbose=None, optionflags=0)[source]#

Bases: DocTestRunner

summarize(out, verbose=None)[source]#

Print a summary of all the test cases that have been run by this DocTestRunner, and return a tuple (f, t), where f is the total number of failed examples, and t is the total number of tried examples.

The optional verbose argument controls how detailed the summary is. If the verbosity is not specified, then the DocTestRunner’s verbosity is used.

Return type:

Tuple[int, int]

pytest_doctest_docutils.pytest_addoption(parser)[source]#
Return type:

None

pytest_doctest_docutils.pytest_collect_file(file_path, parent)[source]#
pytest_doctest_docutils.pytest_configure(config)[source]#

Disable pytest.doctest to prevent running tests twice.

Todo: Find a way to make these plugins cooperate without collecting twice.

Return type:

None

pytest_doctest_docutils.pytest_unconfigure()[source]#
Return type:

None