Earlier this month, Ian Bicking blogged on the inadequacies of the standard unittest module. Reading through the discussion and comments thread is enlightening. Ian’s complaints are:
While I can see Ian’s points, I don’t feel his pain; the unittest module is perfectly adequate for my unit testing needs. I think the big difference is in our approaches to unit testing.1
When working on a system, I try to run all the unit tests every five or ten minutes. All I really need to know is whether the tests pass or fail. When they fail I know the bug must have been introduced in the code I was just working on.
The unittest module supports this quite well. I can a TestCase class for each major piece of functionality to be tested, with multiple testXXX() methods, each containing maybe five or ten individual tests. While not recommended by the unittest documentation, I find it handy to use the Python assert keyword rather than the TestCase testing methods.
Doing it this way:
A. Boiler-plate accounts for only a small percentage of the test code—maybe 10 or 15%, which is mostly the def and class statements.
B. The unittest.main() function supports running all the tests on a TestCase class, or an individual testXXX() method on a class, something you lose if you define your own TestCase constructor.
C. No logging of intermediate test results is necessary. The traceback is usually enough to diagnose the failure, otherwise it is time to insert a few print statements or break out the debugger.2
D. Nor is it necessary to see what the failures would have been had test continued on. Usually, I have done such little coding between test runs, that I have had time to introduce only one bug. If not, I’ll find out when I run the tests again.
This method relies upon is the ability to run the tests quickly. For larger systems, I need to split the tests into separate suites. All the tests are still run, but I run the suites pertaining to the current code more frequently.
All that said, one of Python’s strengths is the active, eclectic community it supports. It was great to see references to so many other unit test libraries and extensions to the unittest module on the comments to Ian’s blog entry. Among them were:
—————
1 I’m certainly not claiming that my unit testing method is better than Ian’s, just different.
2 I drop ”import pdb ; pdb.set_trace()” into suspect code to start a debug session.
Comments
TestOOB (http://testoob.sourceforge.net) is a Python unit testing framework that extends and integrates seamlessly with module 'unittest' (PyUnit).
It works with existing test suites, and provides features such as color console output, examining failed tests with pdb, easy and powerful filtering of which tests to run, HTML and XML reports, and more!