At [work][lincoln-loop] we’ve decided to use [Hudson][hudson] for our continuous integration server.
I started off using [Joe Heck's great Python and Hudson writeup][python-hudson] as a guide.
But to get really good reporting, including a coverage report, you’re going to want to use [Nose][nose], [django-nose][django-nose], and my [nose-xcover][nose-xcover] plugin.
Before you get [Hudson][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][pip]. If you’re not using [pip][pip], I can’t be held responsible if the [central committee][pip-propaganda] gets ahold of you.
Why use [my fork of nose][heisel-nose]? We’ll get to that in a second. First let’s set up our build script.
1. We change into Hudson workspace set up for this build
2. Set up a [virtualenv][virtualenv] for our project
3. Activate it
4. Install our application’s requirements
5. Install our application’s test requirements
6. Assuming you have a properly constructed setup.py, this command will symlink it into your virtualenv’s site packages
7. 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][heisel-nose] listed in our test-requirements.pip. Finally, the –with-xcoverage option activates my [nose-xcover][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.
And then our coverage report, you’ll need the [Cobertura plugin][cobertura] for this:
That’s right, you’ll also want the [Chuck Norris plugin][chuck]. Why? Because Chuck Norris **can** divide by zero. That’s why.
Also, I’d highly recommend the [Green balls][green] 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:
**Editor’s note:** I updated this post to use my [nose-xcover][nose-xcover] plugin and not my [fork of nose][heisel-nose].