This "tested" decorator assigns decorated_function.test() to call doctest.run_docstring_examples appropriately.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | def tested(fun=None, pre=None, post=None, verbose=False, globs=None):
'''
>>> def my_pre(): print "this will be printed before running tests"
...
>>> def my_post(): print "this will be printed after running tests"
...
>>> @tested(pre=my_pre, post=my_post, verbose=True)
... def foo():
... """
... >>> foo()
... True
... """
... return True
>>> foo.test()
this will be printed before running tests
Finding tests in foo
Trying:
foo()
Expecting:
True
ok
this will be printed after running tests
'''
from sys import _getframe
from doctest import run_docstring_examples
if globs is None:
globs = _getframe(1).f_locals
if fun:
def test():
if callable(pre):
pre()
run_docstring_examples(fun, globs=globs, verbose=verbose, name=fun.__name__)
if callable(post):
post()
fun.test = test
return fun
else:
return lambda fun: tested(fun, pre=pre, post=post, verbose=verbose, globs=globs)
tested = tested(tested, verbose=True)
|
You can't debug all of your functions at once. It makes no sense to run all of a module's doctests at once. You just want to run one function's doctests, tweak it, rinse and repeat until that function passes, then move on to another function, rinse and repeat until your whole application. Known issues include head aches while trying to understand the implicit recursion in "tested.test()".
why use caller's locals as globals? What benefit do you get from using the caller's locals as globals for the tests? If anything, it seems like the default should be to use the decorated function's globals (i.e., fun.func_globals).