Pot: nose
While it does support the unittest module which is included with Python, it also allows for a much simple style using just methods and asserts.
Put the following code into a file called test_basic.py:
def test_addition():
print 2 + 2
assert 2 + 2 == 4
def test_addition_wrong():
print 2 + 3
assert 2 + 3 == 6
Then just run nosetests in the directory where you stored this file. You’ll
get an output indicating, that there is a test failure.
nose is based completely on naming conventions. Make sure your test files and methods all start with test for them to get executed. For assertions, just use assert.
When a test goes wrong you usually need some additional output to know what happened. nose helps you with this by handling print statements nicely. In the example above, as test_addition_wrong fails, you’ll see the output of the print statement print 2 + 3. But the print output of test_addition is suppressed because that test does not fail.
One of my favourite features of nose is Test generators. Often you have a large list of inputs and corresponding expected outputs for a function. Test generators allow you to easily test all of them without having to repeat the test code many times.
An example from a Nektoon test suite:
def test_browsers():
tests = [('Mozilla/4.0 (compatible; MSIE 8.0)', 'msie', '8'),
('Mozilla/4.0 (compatible; MSIE 7.0b)', 'msie', '7')]
for ua, model, version in tests:
yield check_browser, ua, model, version
def check_browser(ua, model, version):
res = parse_ua(ua)
print res
assert res['model'] == model
assert res['version'] == version
The tests list is of course much bigger in our test suite and that’s the beauty of it. Adding a new test is very easy, but nose still provides very meaningful error output in the case of a test failure.
Read the official nose documentation if I was able to wet your appetite.
This post is part of the Python on the toilet series.
Continuous testing with Python
Setup
Now that I’m working in Python I was looking for something similar and I was successful. You’ll need the following:
Then you can execute tdaemon like this in your project directory:
Usage
tdaemon.py --custom-args='--with-growl'
This will continually execute the test suite and notify you with growl about the status as you can see in this screencast:
Demo
Details
To get this working as shown in the screencast I actually had to make some changes.
First nosegrowl didn’t install well using easy_install as the images were missing. So I went ahead and did it manually:
$ hg clone http://hg.assembla.com/nosegrowl $ cd nosegrowl/nose-growl/ $ sed -i.bak 's/growl.start/# growl.start/' nosegrowl/growler.py $ python setup.py install
The 'sed’ command is optional. But I don’t want to be notified when the test suite starts, only when it ends. So I uncomment the growl.start line.
Additionally to make tdaemon less noisy when working with vim I added the swap files to the exclude list. Open the tdaemon.py file and edit the IGNORE_EXTENSIONS line to look like this:
IGNORE_EXTENSIONS = ('pyc', 'pyo', 'swp')