Python Friday #68: Use Doctest to Test Your Documentation

Documentation is an important part of every software project – and probably the most neglected one. Nothing is worse than outdated documentation with examples that no longer work. Python has a great little helper to ensure that your documentation is up to date.

This post is part of my journey to learn Python. You can find the other parts of this series here.

 

Why doctest?

Useful documentation makes the connection between the concepts and the code. When developers change the code, do they remember to update the documentation? Probably not.

We end up with a documentation full of great little code snippets that look exactly like the thing we need in our code. But only when we try to run those snippets we see that they no longer work. What a big disappointment and an even bigger waste of time.

The doctest module in Python searches for pieces of text that look like an interactive Python session, converts that into a test and checks if the output matches the one from your documentation. All you need to do is to add a usage example for your code into the docstring of your functions:

 

Run doctest

The test runner for docstring is not as elaborate as unittest or pytest and you need to specify the file you want to test explicitly:

If everything is in order, you will get no output. That is not the best user experience, especially when you make your first steps with doctest. A better way to run doctest is with the -v option, that lists all the tests it made on your documentation:

Trying:
is_even(4)
Expecting:
True
ok
Trying:
is_even(5)
Expecting:
False
ok
1 items had no tests:
doctestexample
1 items passed all tests:
2 tests in doctestexample.is_even
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

 

Detect errors in your documentation

Should your code change but not your documentation, doctest will report all examples that no longer work:

***************************************************
File “.\doctestexample.py”, line 5, in doctestexample.is_even
Failed example:
is_even(4)
Expected:
True
Got:
False
***************************************************
File “.\doctestexample.py”, line 10, in doctestexample.is_even
Failed example:
is_even(5)
Expected:
False
Got:
True
***************************************************
1 items had failures:
2 of 2 in doctestexample.is_even
***Test Failed*** 2 failures.

 

Run doctest with pytest

If we run pytest with the --doctest-modules option it will run the doctest test cases together with all other tests:

The more you use doctest, the more annoying it gets to add the doctest option to the command line. You can get rid of this extra option with an entry in the pytest.ini file (in the root of your project):

If you already have a line for addopts, then add the option for doctest at the end of that line.

 

Next

Doctest is a safety net that enforces correct examples as part of your build pipeline. Unfortunately, not every documentation is as simple as the example I used here. Next week we look at more dynamic output and how we can test that with doctest.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.