5.2 doctest -- Test docstrings represent reality

# 5.2 `doctest` -- Test docstrings represent reality

The `doctest` module searches a module's docstrings for text that looks like an interactive Python session, then executes all such sessions to verify they still work exactly as shown. Here's a complete but small example:

    """
    This is module example.

    Example supplies one function, factorial.  For example,

    >>> factorial(5)
    120
    """

    def factorial(n):
        """Return the factorial of n, an exact integer >= 0.

        If the result is small enough to fit in an int, return an int.
        Else return a long.

        >>> [factorial(n) for n in range(6)]
        [1, 1, 2, 6, 24, 120]
        >>> [factorial(long(n)) for n in range(6)]
        [1, 1, 2, 6, 24, 120]
        >>> factorial(30)
        265252859812191058636308480000000L
        >>> factorial(30L)
        265252859812191058636308480000000L
        >>> factorial(-1)
        Traceback (most recent call last):
            ...
        ValueError: n must be >= 0

        Factorials of floats are OK, but the float must be an exact integer:
        >>> factorial(30.1)
        Traceback (most recent call last):
            ...
        ValueError: n must be exact integer
        >>> factorial(30.0)
        265252859812191058636308480000000L

        It must also not be ridiculously large:
        >>> factorial(1e100)
        Traceback (most recent call last):
            ...
        OverflowError: n too large
        """

        import math
        if not n >= 0:
            raise ValueError("n must be >= 0")
        if math.floor(n) != n:
            raise ValueError("n must be exact integer")
        if n+1 == n:  # catch a value like 1e300
            raise OverflowError("n too large")
        result = 1
        factor = 2
        while factor <= n:
            try:
                result *= factor
            except OverflowError:
                result *= long(factor)
            factor += 1
        return result

    def _test():
        import doctest, example
        return doctest.testmod(example)

    if __name__ == "__main__":
        _test()

If you run example.py directly from the command line, `doctest` works its magic:

    $ python example.py
    $

There's no output! That's normal, and it means all the examples worked. Pass -v to the script, and `doctest` prints a detailed log of what it's trying, and prints a summary at the end:

    $ python example.py -v
    Running example.__doc__
    Trying: factorial(5)
    Expecting: 120
    ok
    0 of 1 examples failed in example.__doc__
    Running example.factorial.__doc__
    Trying: [factorial(n) for n in range(6)]
    Expecting: [1, 1, 2, 6, 24, 120]
    ok
    Trying: [factorial(long(n)) for n in range(6)]
    Expecting: [1, 1, 2, 6, 24, 120]
    ok
    Trying: factorial(30)
    Expecting: 265252859812191058636308480000000L
    ok

And so on, eventually ending with:

    Trying: factorial(1e100)
    Expecting:
    Traceback (most recent call last):
        ...
    OverflowError: n too large
    ok
    0 of 8 examples failed in example.factorial.__doc__
    2 items passed all tests:
       1 tests in example
       8 tests in example.factorial
    9 tests in 2 items.
    9 passed and 0 failed.
    Test passed.
    $

That's all you need to know to start making productive use of `doctest`! Jump in. The docstrings in doctest.py contain detailed information about all aspects of `doctest`, and we'll just cover the more important points here.