headerphoto

Cover Your Nose When You Test

Posted by Tim Freund Wed, 24 Sep 2008 06:06:00 GMT

My mom always reminded me to cover my nose when I sneezed. Now I take it a step further, and I cover my nose when I test.

Nose and the nosetest command are used to run unit tests for Pylons and TurboGears 2 applications, as well as a multitude of other Python applications and libraries. Although nose is great at running tests and reporting back issues, it doesn't natively show developers what isn't being tested. For that, we need a code coverage tool.

Just because nose doesn't handle code coverage reports natively doesn't mean this will be a difficult task. Ned Batchelder's coverage package provides exactly those reports, and nose ships with a plugin to enable it. To install coverage and invoke the reports, you could do something like this:

$ easy_install coverage
$ nosetests --with-coverage  

Name                                         Stmts   Exec  Cover   Missing
--------------------------------------------------------------------------
_strptime                                      228    149    65%   23, 80, 84-89, 155, 169-170, 175, 189, 237, 280-294, 303-304, 306, 314-323, 329, 332, 353-360, 366, 368, 374-388, 393-427, 431-432, 443-446
encodings.ascii                                 19      0     0%   9-42
ez_setup                                       103     11    10%   53-62, 80-104, 117-151, 156-190, 197-222, 226-229
fixture                                         10      9    90%   38
fixture.base                                   124     33    26%   10-19, 25-28, 48-49, 56, 60, 64, 98, 103-104, 122-217
fixture.dataset                                301    225    74%   41, 51-52, 55-59, 65, 76-77, 80, 98-110, 141, 144, 225-229, 232-239, 243-248, 277, 285-289, 323-325, 447-450, 456-457, 461, 468, 479, 483, 529-530, 560-564, 571-574, 580, 631, 720-722, 725-737, 740-744, 752-753
... lots of lines cut to keep you from going blind ...
zope.interface.ro                               22     22   100%
zope.interface.verify                           45     29    64%   46, 51, 56-61, 66, 70, 75-79, 88, 93, 104, 107, 109, 111
--------------------------------------------------------------------------
TOTAL                                        17257   7646    44%
----------------------------------------------------------------------

Good Gravy, man! That's a big coverage report!?

As cool as it is to know that we can get coverage reports for the entire Pylons/TG2 stack, how about we focus for just a minute on only our project. That's the problem with kids today, no focus.

$ nosetests --with-coverage --cover-package=YOUR_PACKAGE_NAME

OK, that's better. Now the report only shows the coverage for code inside of our package. But, seriously, do we really need to type those arguments every time?

Of course not. Sitting there in the root of your Pylons or TurboGears 2 application is a file named setup.cfg. If I were a betting man, I'd say you've never opened it. Ever. Let's knock the dust off and take a look at it in any decent text editor. We're looking for a section named [nosetests], and since you've never changed the file, it is probably at line 8 and looks just like this:

[nosetests]
with-pylons=test.ini

We can add any additional options for nose in this section. Now is your chance to spring into action. Add the following lines to

with-coverage=true
cover-package=YOUR_PACKAGE_NAME

Save setup.cfg and run your tests. You will see a code coverage report at the end of the test run, and the last two columns will be the most interesting. They show the percentage of the code that was covered and the lines of code that were not covered, respectively. Depending on the outcome of your coverage report, you may be feeling rather smug right now. Stop it, we're not Rails developers, and there is still work to do.

On the other hand, if your code coverage report leaves you feeling a little ashamed of just how much code is uncovered, don't despair. Just knowing what code coverage is and caring about the results of a coverage report already puts you into a minority of all programmers. Pick a block of untested code and write a test. All of the sudden, your numbers are better and you'll start to leave those fly-by-the-seat-of-their-pants programmers in the dust.

Remember that this setup.cfg trick will work with any python application or library that is testable with nose. We happen to be focusing on Pylons and TurboGears because that's what I've been busy using lately. How do you use nose to help you write better code?

Posted in , ,

Bookmark and Share

Comments are disabled