Skip to content


I heart Python doctests

I wrote the doctests for the function below and then wrote the code to satisfy them in a total of about 30 seconds. As an extra plus, these doctests immediately clarify behavior in corner cases.


def has_no(s):
    """
    Return False if string s doesn't have the word 'no' inside.

    >>> has_no('no problem')
    True

    >>> has_no('not really')
    False

    >>> has_no('no')
    True

    >>> has_no('oh nothing')
    False
    """

    if s.lower() == 'no': return True
    if s.lower().startswith('no '): return True
    if s.lower().endswith(' no'): return True
    if ' no ' in s.lower(): return True
    
    return False

Writing tests in any other testing framework would have taken me much longer. Compared to writing these tests with nose, writing this:


assert not has_no('oh nothing')

wouldn’t take me any more time than

>>> has_no('oh nothing')
False

But that’s not all there is to it. With nose, I’d need to open a new test_blah.py file, then import my original blah.py module, then I would have to decide between putting each assert in a separate test function or just writing a single function with all my asserts.

That’s how a 30-second task turns into a 5-minute task.

Anyhow, I’m surprised doctests don’t get a lot more attention. They’re beautiful. Adding tests to an existing code base couldn’t be any simpler. Just load functions into an interpreter and then play around with it (ipython has a %doctest_mode, by the way).

For a lot of simple functions (like the one above) it is easy to just write out the expected results manually rather than record from a session.

It is also possible to store doctests in external text files. The Django developers use this trick frequently.

Finally, I don’t try to solve every testing problem with doctests. I avoid doctests when I need elaborate test fixtures or mock objects. Most of my modules have a mix of functions with doctests and nose tests somewhere else to exercise the weird or composite stuff.

Incidentally, this post is where Tim Peters introduced the doctests module.

Posted in Programming, Python, Testing.

Viewing 13 Comments

 
close Reblog this comment
blog comments powered by Disqus