Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources]

David Ascher, Alex Martelli, Anna Ravenscroft

نسخه متنی -صفحه : 394/ 187
نمايش فراداده

Recipe 8.8. Running Unit Tests Most Simply

Credit: Justin Shaw

Problem

You find the test runners in standard library module unittest to be less than optimally simple, and you want to ensure that running unit tests is so simple and painless as to leave simply no excuse for not testing regularly and copiously.

Solution

Save the following code in module microtest.py somewhere along your Python sys.path:

import types, sys, traceback
class TestException(Exception): pass
def test(modulename, verbose=None, log=sys.stdout):
''' Execute all functions in the named module which have _ _test_ _
in their name and take no arguments.
modulename:  name of the module to be tested.
verbose:     If true, print test names as they are executed
Returns None on success, raises exception on failure.
'''
module = _ _import_ _(modulename)
total_tested = 0
total_failed = 0
for name in dir(module):
if '_ _test_ _' in name:
obj = getattr(module, name)
if (isinstance(obj, types.FunctionType) and
not obj.func_code.co_argcount):
if verbose:
print>>log, 'Testing %s' % name
try:
total_tested += 1
obj( )
except Exception, e:
total_failed += 1
print>>sys.stderr, '%s.%s FAILED' % (modulename, name)
traceback.print_exc( )
message = 'Module %s failed %s out of %s unittests.' % (
modulename, total_failed, total_tested)
if total_failed:
raise TestException(message)
if verbose:
print>>log, message
def _ _test_ _( ):
print 'in _ _test_ _'
import pretest
pretest.pretest('microtest', verbose=True)

Discussion

Module unittest in the Python Standard Library is far more sophisticated than this simple microtest module, of course, and I earnestly urge you to study it. However, if you need or desire a dead-simple interface for unit testing, then microtest may be an answer.

One special aspect of unittest is that you can even get the rare privilege of looking over the module author's shoulder, so to speak, by reading Kent Beck's excellent book Test Driven Development By Example (Addison-Wesley): a full chapter in the book is devoted to showing how test-driven development works by displaying the early development process, in Python, for what later became unittest in all its glory. Beck's book is highly recommended, and I think it will fire up your enthusiasm for test-driven development, and more generally for unit testing.

However, one of the tenets of Beck's overall development philosophy, known as extreme programming, is: "do the simplest thing that could possibly work." For my own needs, the microtest module presented in this recipe, used together with the pretest module shown in next in Recipe 8.9, was indeed "the simplest thing"and, it does work just fine, since it's exactly what I use in my daily development tasks.

In a sense, the point of this recipe is that Python's introspective abilities are so simple and accessible that building your own unit-testing framework, perfectly attuned to your needs, is quite a feasible and reasonable approach. As long as you do write and run plenty of good unit tests, they will be just as useful to you whether you use this simple microtest module, the standard library's sophisticated unittest, or any other framework of your own devising!

See Also

Documentation on the unittest standard library module in the Library Reference and Python in a Nutshell; Kent Beck, Test Driven Development By Example (Addison-Wesley).