Recipe8.9.Running Unit Tests Automatically


Recipe 8.9. Running Unit Tests Automatically

Credit: Justin Shaw

Problem

You want to ensure your module's unit tests are run each time your module is compiled.

Solution

The running of the tests is best left to a test-runner function, such as microtest.test shown previously in Recipe 8.8. To make it automatic, save the following code in a module file pretest.py somewhere on your Python sys.path. (If you are using a test-runner function other than microtest.test, change the import statement and the runner=microtest.test default value.)

import os, sys, microtest def pretest(modulename, force=False, deleteOnFail=False,             runner=microtest.test, verbose=False, log=sys.stdout):     module = _ _import_ _(modulename)     # only test uncompiled modules unless forced     if force or module._ _file_ _.endswith('.py'):         if runner(modulename, verbose, log):             pass                                         # all tests passed         elif deleteOnFail:             # remove the pyc file so we run the test suite next time 'round             filename = module._ _file_ _             if filename.endswith('.py'):                 filename = filename + 'c'             try: os.remove(filename)             except OSError: pass

Now, you just have to include in each of your modules' bodies the code:

import pretest if _ _name_ _ != '_ _main_ _':    # when module imported, NOT run as main script     pretest.pretest(_ _name_ _)

Discussion

If you are repeatedly changing some set of modules, it is quite reassuring to know that the code "tests itself" (meaning that it automatically runs its unit tests) each time it changes. (Each time it changes is the same as each time the module gets recompiled. Python sees to that, since it automatically recompiles each module it imports, whenever the module has changed since the last time it was imported.) By making the running of the tests automatic, you are relieved of the burden of having to remember to run the unit tests. Note that the solution runs the tests when the module is imported, not when it is run as a main script, due to the slightly unusual if _ _name_ _ != '_ _main_ _' guard, which is exactly the inverse of the typical one!

Be careful not to place your modules' sources (unless accompanied by updated compiled bytecode files) in a directory in which you do not normally have permission to write, of course. It is a bad idea in any case, since Python, unable to save the compiled .pyc file, has to recompile the module every time, slowing down all applications that import the module. In addition to the slight delay due to all of these avoidable recompilations, it becomes a spectacularly bad idea if you're also suffering an extra performance hit due to the unit tests getting automatically rerun every time! Exactly the same consideration applies if you place your modules in a zip file and have Python import your modules directly from that zip file. Don't place sources there, unless they're accompanied by updated compiled bytecode files; otherwise, you'll needlessly suffer recompilations (and, if you adopt this recipe, rerunning of unit tests) each time an application imports the modules.

See Also

Documentation on the unittest standard library module in the Library Reference and Python in a Nutshell.



Python Cookbook
Python Cookbook
ISBN: 0596007973
EAN: 2147483647
Year: 2004
Pages: 420

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net