November 21, 2009
Django continuous integration with Hudson and Nose
At work we’ve decided to use Hudson for our continuous integration server.
I started off using Joe Heck’s great Python and Hudson writeup as a guide.
But to get really good reporting, including a coverage report, you’re going to want to use Nose, django-nose, and my nose-xcover plugin.
Before you get Hudson up and running, you’ll first want to create a test settings module for your application. Here’s a sample:
With that in place you’ll want to set up a separate test requirements file for pip. If you’re not using pip, I can’t be held responsible if the central committee gets ahold of you.
Why use my fork of nose? We’ll get to that in a second. First let’s set up our build script.
- We change into Hudson workspace set up for this build
- Set up a virtualenv for our project
- Activate it
- Install our application’s requirements
- Install our application’s test requirements
- Assuming you have a properly constructed setup.py, this command will symlink it into your virtualenv’s site packages
- Finally run our tests, using our test settings.
The –with-coverage option tells nose we want to capture coverage information. The –cover-package option tells nose we only want reporting on our application. The –with-xunit option will generte a nosetests.xml file in our workspace with the results of the test run.
Finally, the –with-cover-xml option is an option I added to nose’s coverage plugin, and the reason why I’ve got my fork listed in our test-requirements.pip. Finally, the –with-xcoverage option activates my nose-xcover plugin. It outputs an XML coverage report that Hudson can use, and it’ll honor the –cover-package option you specified earlier, so your coverage percentage won’t be artificially lowered, or inflated, by third-party code you use.
Now let’s configure Hudson to use the two XML reports we’re generating.
First the test pass/fail report.
![Config [Hudson].jpg](http://heisel.org/blog/wp-content/uploads/2009/11/Config-Hudson.jpg)
And then our coverage report, you’ll need the Cobertura plugin for this:
![Config [Hudson]-1.jpg](http://heisel.org/blog/wp-content/uploads/2009/11/Config-Hudson-1.jpg)
That’s right, you’ll also want the Chuck Norris plugin. Why? Because Chuck Norris can divide by zero. That’s why.
Also, I’d highly recommend the Green balls plugin, because Hudson’s default of blue == pass just doesn’t fly with me, or Chuck.
While we’ve been setting up Hudson, I had another build in the oven baking using the recipe above. Let’s see how it turned out:
![Dummy [Hudson].jpg](http://heisel.org/blog/wp-content/uploads/2009/11/Dummy-Hudson.jpg)
Editor’s note: I updated this post to use my nose-xcover plugin and not my fork of nose.
Filed under: Django, Programming, Python, Technology
Next: For Christmas, vintage photos
Previous: Setup Django with mod_wsgi on your Mac
Comments
Joe Heck – November 22, 2009 #
Nice writeup! I’ve been wondering about nose & django together, but hadn’t yet found the django-nose piece.
Did you have to do much work on the system hosting Hudson to enable virtualenv? Would love to see/hear what you specific build steps look like for this setup.
Chris – November 23, 2009 #
Joe,
Didn’t have to do much to get it to use the virtualenv.
I’m running the tests via a shell job, so all I had to do was create the virtualenv and source it.
This gist http://gist.github.com/240296 is pretty much our build command. Then we have one other build command for pylint using what you had in your tutorial.
Stavros – December 10, 2009 #
Hello, I love your guide (and the final result), but I don’t like having to install a fork of official packages (it’s a bit hard to maintain). Do you think your changes could ever see their way upstream?
Chris Heisel – December 10, 2009 #
Stavros,
Thanks! Two thoughts, you can give the folks at Nose a ping, I sent the maintainer a pull request on BitBucket, but haven’t heard back.
I’ll also look and see if I can make a plugin that’d do the same thing my patch is doing.
Chris
Chris – December 12, 2009 #
Stavros,
Give this plugin I whipped up a try, it should compliment nose’s built-in coverage plugin, adding the XML output: nose-xcover
Stavros – December 30, 2009 #
I just tried your plugin, it is much better and I have gotten everything working fine (after setting up your plugin nose couldn’t find it, but I copied the module manually in /site-packages/). The coverage and nosetests xml files are generated fine, but for some reason Hudson reports my tests as failed, even though nosetests.xml has failures=”0″…
I’ll figure it out sooner or later, thanks for granting my request!
Stavros – December 30, 2009 #
Hmm, tests pass but Hudson reports a failed build. Could this be because I’m just running manage.py test?
Stavros – December 30, 2009 #
Word to the wise, don’t use the pypi version of django-nose, get the one from github.
jacob – February 13, 2010 #
Hi Chris, First, apologies, I’m a python/django noob. When you say to “create a test settings module for your application,” what exactly does this mean? If I merely parse the statement word-by-word, given my rudimentary knowledge, I take it that I should create a file with a .py extension (i.e. a module) in (one of (or all of?)) the application directories in my django project. Is that correct? If so, does it matter what the module is named? Is something somewhere supposed to refer to it? Which of my django applications should contain it? Where exactly in the dir structure of the application should it go? Does this assume one Hudson project per django app?
Chris – February 22, 2010 #
Jacob,
The settings module is a regular python file that can live anywhere on your Python path. It’s documented on the “Django Web site”:http://docs.djangoproject.com/en/1.1/topics/settings/
Often times folks will have a settings module in their project folder, or if you’re building a reusable application you might have a settings file for testing inside that application.
My Hudson configuration doesn’t assume one application per Hudson project. You could run a large test suite containing many applications if you wanted.
Jacob – March 4, 2010 #
Thanks!
Tobias McNulty – March 11, 2010 #
As another resource, Colin, one of the guys I work with, just did a writeup of our Django/Hudson setup here at Caktus:
http://www.caktusgroup.com/blog/2010/03/08/django-and-hudson-ci-day-1/
It walks you through setting up a new Hudson installation to test a Django project – hope someone finds it useful!