5.2 doctest -- Test docstrings represent reality
Keywords: lib

# 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:  # e.g., 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.

Subsections

- 5.2.1 Normal Usage
- 5.2.2 Which Docstrings Are Examined?
- 5.2.3 What's the Execution Context?
- 5.2.4 What About Exceptions?
- 5.2.5 Advanced Usage
- 5.2.6 How are Docstring Examples Recognized?
- 5.2.7 Warnings
- 5.2.8 Soapbox