Python ships with a standard module unittest. Per the Python docs:
The Python unit testing framework, sometimes referred to as “PyUnit,” is a Python language version of JUnit, by Kent Beck and Erich Gamma. JUnit is, in turn, a Java version of Kent’s Smalltalk testing framework. Each is the de facto standard unit testing framework for its respective language.
unittest supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework. The unittest module provides classes that make it easy to support these qualities for a set of tests.
Unittest is great, but -- as you'll see -- requires a lot of boiler plate code to get up and running. In fact, I would argue that unittest kind of gets in the way of functional testing. Luckily, there's nose.
Doug Hellmann's PyMOTW has an excellent article on Python's unittest. Before we dive in, let's make sure you're setup:
[terryp@tpmacbook] ~ :: python Python 2.5.4 (r254:67917, Dec 23 2008, 14:57:27) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import unittest >>> print unittest.__version__ 1.63 >>>
Awesome. All set. Now let's write a simple test called 'unittest_toy.py:'
import unittest class ToyTest(unittest.TestCase): def test(self): self.assertTrue(True) if __name__ == "__main__": unittest.main()
OK, now let's run it:
[terryp@tpmacbook] code :: python unittest_toy.py . ---------------------------------------------------------------------- Ran 1 test in 0.000s OK
We get a '.' that says we ran one successful test! Chad Whitacre, when on the Testing Panel at PyCon 2007 in Dallas, summarized the significance of dots when he said, "I'm addicted to dots." When I first heard that, I kind of didn't get it, but when you see a screen full of dots there's something incredibly satisfying about it.
So now that we've examined the basics of UnitTest, let's contrast the simple test case we've written with Nose. Nose, although fully compatible with unittest, has a slightly different approach to running tests. Let's rewrite 'unittest_toy.py' as a nose test, 'test_toy.py.'
def test_toy(): assert True
Yep, that's really it. No imports, no classes, no subclasses, no boilerplate code. Okay, let's run it.
[terryp@tpmacbook] code :: nosetests test_toy.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Took a millisecond longer, but as you can see, we get the same output. Nose, we think, lowers the barrier to writing tests. You don't have to worry about syntax as much, and you can just start testing code quickly without thinking too much about it.
Nose, however, does have a few caveats that you have to follow to make compatible tests:
If you prefix your test modules with 'test_*' and your test functions within your modules with 'test_*' you'll be good to go.
Oh, and remember how we said nose can run unittests? Let's try it!
[terryp@tpmacbook] code :: nosetests unittest_toy.py . ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Fluid 960 Grid System, created by Stephen Bau, based on the 960 Grid System by Nathan Smith. Released under the GPL/ MIT Licenses.