I have a sample doctest like this one.
"""
This is the "iniFileGenerator" module.
>>> hintFile = "./tests/unit_test_files/hint.txt"
>>> f = iniFileGenerator(hintFile)
>>> print f.hintFilePath
./tests/unit_test_files/hint.txt
"""
class iniFileGenerator:
def __init__(self, hintFilePath):
self.hintFilePath = hintFilePath
def hello(self):
"""
>>> f.hello()
hello
"""
print "hello"
if __name__ == "__main__":
import doctest
doctest.testmod()
When I execute this code, I got this error.
Failed example:
f.hello()
Exception raised:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/doctest.py", line 1254, in __run
compileflags, 1) in test.globs
File "<doctest __main__.iniFileGenerator.hello[0]>", line 1, in <module>
f.hello()
NameError: name 'f' is not defined
This error is caused by accessing 'f' which was not accessible when testing hello()
method.
Is there any way to share the object which is created before? Without it, one need to create object all the time when it's necessary.
def hello(self):
"""
hintFile = "./tests/unit_test_files/hint.txt"
>>> f = iniFileGenerator(hintFile)
>>> f.hello()
hello
"""
print "hello"
When the tests include values that are likely to change in unpredictable ways, and where the actual value is not important to the test results, you can use the ELLIPSIS option to tell doctest to ignore portions of the verification value.
Doctests are specified by an indentation of four spaces followed by the iex> prompt in a documentation string. If a command spans multiple lines, you can use ...> , as in IEx. The expected result should start at the next line after iex> or ...> line(s) and is terminated either by a newline or a new iex> prefix.
Which of the following is a valid doctest ? Answer: y def add ( x , 2. A sample function sample_fuc is defined as shown below .
You can use testmod(extraglobs={'f': initFileGenerator('')})
to define a reusable object globally.
As the doctest doc says,
extraglobs gives a dict merged into the globals used to execute examples. This works like dict.update()
But I used to test all methods in __doc__
of class before all methods.
class MyClass(object):
"""MyClass
>>> m = MyClass()
>>> m.hello()
hello
>>> m.world()
world
"""
def hello(self):
"""method hello"""
print 'hello'
def world(self):
"""method world"""
print 'world'
To obtain literate modules with tests that all use a shared execution context (i.e. individual tests that can share and re-use results), one has to look at the relevant part of documentation on the execution context, which says:
... each time
doctest
finds a docstring to test, it uses a shallow copy ofM
‘s globals, so that running tests doesn’t change the module’s real globals, and so that one test inM
can’t leave behind crumbs that accidentally allow another test to work....
You can force use of your own dict as the execution context by passing
globs=your_dict
totestmod()
ortestfile()
instead.
Given this, I managed to reverse-engineer from doctest
module that besides using copies (i.e. the dict
's copy()
method), it also clears the globals dict (using clear()
) after each test.
Thus, one can patch their own globals dictionary with something like:
class Context(dict):
def clear(self):
pass
def copy(self):
return self
and then use it as:
import doctest
from importlib import import_module
module = import_module('some.module')
doctest.testmod(module,
# Make a copy of globals so tests in this
# module don't affect the tests in another
glob=Context(module.__dict__.copy()))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With