Beginners’ Guide to Effortless Doctests in Python

Doctests are essentially tests embedded in a docstring. They serve both as example use cases and test cases! A Python expression is provided along with an expected outcome, a test runner collects that and evaluates the expression.

Getting started

Let’s take a look at a run-of-the-mill docstring.

It’s a normal docstring with nothing too special. Let’s try to get the doctest module to test our test-less function.

Well, the output says it clear that we have no tests. Now, let’s add a doctest. Remember how the Python Shell or REPL works? Remember how you have three arrows indicating input? Yes. Just copy that style.

Time to run the doctest module again.

Ah, that looks more like it.

Expecting Exceptions

Let’s try something more fun. Let’s add a case in our function, if the provided name is just composed of digits, we refuse to greet digits!

Now, how do we test for exceptions? Well, remember the mantra.

Replicate your shell; success you will be showered with upon you.

So, just replicate your shell! Let’s see how the shell reacts to digits.

So, in the doctest,

Just the first line and the last line of the exception. Don’t confuse doctest with a complete, well-formatted and fully laid out stack trace, please! And just three dots to indicate there were more to it. So, let’s run this again.

And yes.

In Production

Of course, in production, you do need to use a test runner. Something in the category of pytest or nose. I personally prefer pytest. Let’s take a look at configuring pytest for this.

Not so surprisingly, it discovered no tests in the default configuration. We need to add a simple flag to it --doctest-modules .

That seems to be working, let’s try to intentionally run our tests to check if it is really working.

And that is working perfectly. To avoid putting the –doctest-modules flag all the time, consider making a tox.ini file to place your pytest configuration. More on this in the pytest documentation.

Leave a Reply

Your email address will not be published. Required fields are marked *

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