Doctests in TestCase classes

The original doctest unittest integration was based on unittest test suites, which have fallen out of favor. This module provides a way to define doctests inside of unittest.TestCase classes. It provides better integration with unittest test fixtures, because doctests use setup provided by the containing test case class. It provides access to unittest assertion methods.

You can define doctests in multiple ways:

  • references to named files

  • strings

  • decorated functions with docstrings

  • reference to named files decorating test-specific setup functions

  • reference to named files decorating a test class

Here are some examples:

>>> from zope.testing import doctestcase
>>> import doctest
>>> import unittest

>>> g = 'global'

>>> class MyTest(unittest.TestCase):
...     def setUp(self):
...         self.a = 1
...         self.globs = dict(c=9)
...     test1 = doctestcase.file('test-1.txt', optionflags=doctest.ELLIPSIS)
...     test2 = doctestcase.docteststring('''
...       >>> self.a, g, c
...       (1, 'global', 9)
...     ''')
...     @doctestcase.doctestmethod(optionflags=doctest.ELLIPSIS)
...     def test3(self):
...         '''
...         >>> self.a, self.x, g, c
...         (1, 3, 'global', 9)
...         '''
...         self.x = 3
...     @doctestcase.doctestfile('test4.txt')
...     def test4(self):
...         self.x = 5

>>> class MissingDocstring(unittest.TestCase):  
...     """A doctest method has to have a docstring."""
...     @doctestcase.doctestmethod(optionflags=doctest.ELLIPSIS)
...     def test55(self):
...         pass
Traceback (most recent call last):
ValueError: (<function ...test55 at 0x...>, 'has no docstring')
>>> import sys

>>> @doctestcase.doctestfiles('loggingsupport.txt', 'renormalizing.txt')
... class MoreTests(unittest.TestCase):
...    def setUp(self):
...        def print_(*args):
...            sys.stdout.write(' '.join(map(str, args))+'\n')
...        self.globs = dict(print_=print_)

In these examples, 4 constructors were used:

doctestfile (alias: file)

doctestfile makes a file-based test case.

This can be used as a decorator, in which case, the decorated function is called before the test is run, to provide test-specific setup.

doctestfiles (alias: files)

doctestfiles makes file-based test cases and assigns them to the decorated class.

Multiple files can be specified and the resulting doctests are added as members of the decorated class.

docteststring (alias: string)

docteststring constructs a doctest from a string.

doctestmethod (alias: method)

doctestmethod constructs a doctest from a method.

The method’s docstring provides the test. The method’s body provides optional test-specific setup.

Note that short aliases are provided, which maye be useful in certain import styles.

Tests have access to the following data:

  • Tests created with the docteststring and doctestmethod constructors have access to the module globals of the defining module.

  • In tests created with the docteststring and doctestmethod constructors, the test case instance is available as the self variable.

  • In tests created with the doctestfile and doctestfiles constructor, the test case instance is available as the test variable.

  • If a test case defines a globs attribute, it must be a dictionary and it’s contents are added to the test globals.

The constructors accept standard doctest optionflags and checker arguments.

Note that the doctest IGNORE_EXCEPTION_DETAIL option flag is added to optionflags.

When using doctestfile and doctestfile, filename and filepath attributes are available that contain the test file name and full path.

__name__ attributes of class members

Class members have __name__ attributes set as follows:

  • When using doctestmethod or doctestfile with a setup function, __name__ attribute is set to the name of the function. A test_ prefix is added, if the name doesn’t start with test.

  • When doctestfile is used without a setup function or when doctestfiles is used, __name__ is set to the last part of the file path with the extension removed and non-word characters converted to underscores. For example, with a test path of '/foo/bar/test-it.rst', the __name__ attribute is set to 'test_it'. A test_ prefix is added, if the name doesn’t start with test.

  • when using docteststring, a name option can be passed in to set __name__. A test_ prefix is added, if the name doesn’t start with test.

The __name__ attribute is important when using nose, because nose discovers tests as class members using their __name__ attributes, whereas the unittest and py.test test runners use class dictionary keys.