This is part 3 of a series.

In part 1 we set up a Hudson test server, and in part 2 I introduced a simple Django application with some simple tests.

Now we're going to make Hudson run those simple tests. Prerequisites: Your box for running this application must be able to run both Hudson and Django, and you must, for our purposes, include all of the things we put into our application, such as BeautifulSoup and Coverage. To make this demonstration work, you must also install Linus Torvald's Git source control manager (or, you can figure out how to make this example work with any SCM of your own, such as Subversion or Mercurial).

Git

First, let's put our project under Git. Untar the existing source file somewhere, preferably as a different user, go into the directory and type this:

git init
git add .
git commit -a

You'll be asked to make a comment, at which point your project will be under Git control. If you want to know more about Git, read up on it, because it is a very cool SCM.

Hudson

Now we need to make Hudson aware of GIT. It doesn't come naturally. Go to your Hudson URL, log in, and click Manage Hudson -> Manage Plugins -> Available Pick "Git" (not "Github"), go to the bottom of the list, and save.

Now, on your console, log in as your Hudson user (yes, you must do this step), and make Git aware of who you are, or Hudson won't be able to run it. The steps are simple:

git config --global user.email "usre@somenonexistentsite.com"
git config --global user.name  "Elf Sternberg"

Now, back at the Hudson dashboard, pick New Job, give the job a name and choose Build a free-style software project. Click Ok.

On the job configuration page, pick Git under SCM, and in the "URL of repository" put the path to your repository. In mine, it was: file:///home/elfsternberg/build/echodemo

For build triggers pick Build periodically, and in the Build section pick Execute Shell. Now, in that execute block enter our command:

./manage.py test receiver

There is one change you're likely to have to make. In echodemo's file settings.py change ROOT_URLCONF to read:

ROOT_URLCONF = 'urls'

This allows Hudson to run your application without needing the project directory to be named "echodemo". By default, Hudson names it "workspace."

Now, I could have been smart about this and used virtualenv, and saved everything under git. Or at the very least saved it in a subdirectory and use a simple change directory command. But for now, this will do.

So, make that change, git commit -a the change, and return to Hudson. Go to your project and click on Build Now.

If everything's good, your build should run fine. You should get a blue ball (unless you installed the green balls plug-in, which a lot of people do), and after you go to the build's status page, select console output and you should see Hudson's output, finishing up with these happy lines:

Ran 1 test in 0.159s

OK
Creating test database...
Creating table sender_sentmessage
Creating table receiver_receivedmessage
Destroying test database...
Finished: SUCCESS

Now, go back to the Project Configuration in Hudson, and change the "execute shell" command to read:

coverage run ./manage.py test receiver; coverage report -m

Save, go back, and select Build Now again. If everything goes according to plan, your happy ending should read:

+ coverage report -m
Name                Stmts   Exec  Cover   Missing
-------------------------------------------------
__init__                1      1   100%
manage                  9      5    55%   5-8
receiver/__init__       1      1   100%
receiver/models        11     10    90%   12
receiver/tests         13     13   100%
receiver/views         18     18   100%
sender/__init__         1      1   100%
sender/models           3      3   100%
settings               23     23   100%
urls                    2      2   100%
-------------------------------------------------
TOTAL                  82     77    93%
Finished: SUCCESS

Congratulations.

You now have a reliable continuous integration test engine for DJango, complete with a code coverage report.  Everything else past this point is extending on our current efforts.