Python Forum
Combine documentation and testing with doctest
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Combine documentation and testing with doctest
#1
Testing is how we verify that a piece of code works as intended.

Doctest allow us to document and test a code unit at once.

A docstring or documentation string is a triple quoted string that appears as the first statement of a code unit.
def add(a, b):
   '''
   Calculates the sum of two numbers.
   '''
   result = f"{a} + {b} = {a + b}"
   return result

print(add.__doc__, end = '\n')

print(add(10, 20))
Output:
Calculates the sum of two numbers. 10 + 20 = 30
In the above function, the docstring is the tripple quoted string in the functions body, we accessed it using the __doc__ attribute.

Doctests are written as a part of the docstring. Consider the following example:
#foo.py 

def add(a, b):
   '''
   Calculates the sum of two numbers.

   >>> add(10, 20)
   '10 + 20 = 30'
   >>> add(50, 40)
   '50 + 40 = 90'
   >>> add(-5, 10)
   '-5 + 10 = 5'
   '''
   result = f"{a} + {b} = {a + b}"
   return result
In the above example, we defined the add function in a file called foo.py. A part of the function's docstring look as if it has been copied directly from an interactive session. Those are actually valid tests and we can execute them by calling the builtin doctest library.

To run the tests, open the shell/cmd and move where the foo.py file is located, then run the following command:
python -m doctest foo.py -v
Output:
Trying: add(10, 20) Expecting: '10 + 20 = 30' ok Trying: add(50, 40) Expecting: '50 + 40 = 90' ok Trying: add(-5, 10) Expecting: '-5 + 10 = 5' ok 1 items had no tests: foo 1 items passed all tests: 3 tests in foo.add 3 tests in 2 items. 3 passed and 0 failed. Test passed.
In doctest:
  • Lines starting with >>> are sent to the interpreter for execution.
  • A lines starting with ... are sent as continuation to the previous line.
  • A line that has no any prefix is treated as the expected output of the statement above it.

When we run the doctest command, doctest knows how to locate the tests in the doctstrings. It only collects the tests and ignores regular texts, this makes it possible to have tests and regular texts in the same docstring without affecting execution of the tests.
def add(a, b):
   '''
   Calculates the sum of two numbers.

   >>> add(10, 20)
   '10 + 20 = 30'
   >>> add(50, 50)
   '50 + 50 = 10000'
   >>> add(-5, 10)
   '-5 + 10 = 5'
   
   End of documentation'''
   result = f"{a} + {b} = {a + b}"
   return result
In the above example, we deliberately made a wrong assumption that 50 + 50 = 10000, the tests will therefore fail if we run the doctests command.
Output:
Trying: add(10, 20) Expecting: '10 + 20 = 30' ok Trying: add(50, 50) Expecting: '50 + 50 = 10000' ********************************************************************** File "C:\Users\John\Desktop\foo.py", line 7, in foo.add Failed example: add(50, 50) Expected: '50 + 50 = 10000' Got: '50 + 50 = 100' Trying: add(-5, 10) Expecting: '-5 + 10 = 5' ok 1 items had no tests: foo ********************************************************************** 1 items had failures: 1 of 3 in foo.add 3 tests in 2 items. 2 passed and 1 failed. ***Test Failed*** 1 failures.
See doctests in Python
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020