November 21, 2009

Django continuous integration with Hudson and Nose

At work we’ve decided to use Hudson for our con­tin­u­ous inte­gra­tion server.

I started off using Joe Heck’s great Python and Hudson writeup as a guide.

But to get really good report­ing, includ­ing a cov­er­age report, you’re going to want to use Nose, django-​nose, and my nose-​xcover plugin.

Before you get Hudson up and run­ning, you’ll first want to create a test set­tings module for your appli­ca­tion. Here’s a sample:

With that in place you’ll want to set up a sep­a­rate test require­ments file for pip. If you’re not using pip, I can’t be held respon­si­ble if the cen­tral com­mit­tee 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.

  1. We change into Hudson work­space set up for this build
  2. Set up a vir­tualenv for our project
  3. Acti­vate it
  4. Install our application’s requirements
  5. Install our application’s test requirements
  6. Assum­ing you have a prop­erly con­structed setup.py, this com­mand will sym­link 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 cap­ture cov­er­age infor­ma­tion. The –cover-​package option tells nose we only want report­ing on our appli­ca­tion. The –with-​xunit option will gen­erte a nosetests.xml file in our work­space with the results of the test run.

Finally, the –with-​cover-​xml option is an option I added to nose’s cov­er­age plugin, and the reason why I’ve got my fork listed in our test-requirements.pip. Finally, the –with-​xcoverage option acti­vates my nose-​xcover plugin. It out­puts an XML cov­er­age report that Hudson can use, and it’ll honor the –cover-​package option you spec­i­fied ear­lier, so your cov­er­age per­cent­age won’t be arti­fi­cially low­ered, or inflated, by third-​party code you use.

Now let’s con­fig­ure Hudson to use the two XML reports we’re generating.

First the test pass/fail report.

Config [Hudson].jpg

And then our cov­er­age report, you’ll need the Cober­tura plugin for this:

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 rec­om­mend the Green balls plugin, because Hudson’s default of blue == pass just doesn’t fly with me, or Chuck.

While we’ve been set­ting up Hudson, I had another build in the oven baking using the recipe above. Let’s see how it turned out:

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:
Previous:

Related

Comments

Joe Heck – November 22, 2009 #

Nice writeup! I’ve been won­der­ing about nose & django together, but hadn’t yet found the django-​nose piece.

Did you have to do much work on the system host­ing Hudson to enable vir­tualenv? Would love to see/hear what you spe­cific 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 run­ning the tests via a shell job, so all I had to do was create the vir­tualenv and source it.

This gist http://​gist.​github.​com/​2​40296 is pretty much our build com­mand. Then we have one other build com­mand 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 offi­cial pack­ages (it’s a bit hard to main­tain). 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 main­tainer a pull request on Bit­Bucket, 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 com­pli­ment nose’s built-​in cov­er­age plugin, adding the XML output: nose-​xcover

Stavros – December 30, 2009 #

I just tried your plugin, it is much better and I have gotten every­thing work­ing fine (after set­ting up your plugin nose couldn’t find it, but I copied the module man­u­ally in /site-​packages/). The cov­er­age and nosetests xml files are gen­er­ated 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 grant­ing my request!

Stavros – December 30, 2009 #

Hmm, tests pass but Hudson reports a failed build. Could this be because I’m just run­ning man​age.py test?

Stavros – December 30, 2009 #

Word to the wise, don’t use the pypi ver­sion of django-​nose, get the one from github.

jacob – February 13, 2010 #

Hi Chris, First, apolo­gies, I’m a python/django noob. When you say to “create a test set­tings module for your appli­ca­tion,” what exactly does this mean? If I merely parse the state­ment word-​by-​word, given my rudi­men­tary knowl­edge, I take it that I should create a file with a .py exten­sion (i.e. a module) in (one of (or all of?)) the appli­ca­tion direc­to­ries in my django project. Is that cor­rect? If so, does it matter what the module is named? Is some­thing some­where sup­posed to refer to it? Which of my django appli­ca­tions should con­tain it? Where exactly in the dir struc­ture of the appli­ca­tion should it go? Does this assume one Hudson project per django app?

Chris – February 22, 2010 #

Jacob,

The set­tings module is a reg­u­lar python file that can live any­where on your Python path. It’s doc­u­mented on the “Django Web site”:http://docs.djangoproject.com/en/1.1/topics/settings/

Often times folks will have a set­tings module in their project folder, or if you’re build­ing a reusable appli­ca­tion you might have a set­tings file for test­ing inside that application.

My Hudson con­fig­u­ra­tion doesn’t assume one appli­ca­tion per Hudson project. You could run a large test suite con­tain­ing many appli­ca­tions 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.​cak​tus​group.​com/​b​l​o​g​/​2​0​1​0​/​0​3​/​0​8​/​d​j​a​n​g​o​-​a​n​d​-​h​u​d​s​o​n​-​c​i​-​day-1/

It walks you through set­ting up a new Hudson instal­la­tion to test a Django project – hope some­one finds it useful!