March 15, 2012

Code coverage in django with ‘coverage’ and ‘django-jenkins’

Posted in Software at 18:59 by graham

Getting unit test code coverage in python, and in django, is easy thanks to coverage:

pip install coverage
coverage run manage.py test app1 app2 app3
coverage html --include="my_project/*"
www-browser htmlcov/index.html

A disadvantage of Django’s test runner is that by default it runs tests for all the packages in INSTALLED_APPS. Usually you only want to run tests for your apps, not for third-party libraries. Hence I prefer the test runner in django-jenkins:

pip install django-jenkins

or directly from git (at time of writing the –coverage-html is only in git):

pip install git+git://github.com/kmmbvnr/django-jenkins.git

Edit settings.py to add these lines, changing “my_project” in the last line to your project’s top level package name:

INSTALLED_APPS += ('django_jenkins',)
JENKINS_TASKS = ('django_jenkins.tasks.django_tests',)
PROJECT_APPS = [appname for appname in INSTALLED_APPS if appname.startswith('my_project')]

Now run jtest with coverage, and it will always include all your apps, and only your apps:

manage.py jtest --coverage-html-report=htmlcov

Older versions of django_jenkins don’t have --coverage-html, so use this:

coverage run manage.py jtest
coverage html --include="my_project/*"
www-browser htmlcov/index.html

As the name implies, django-jenkins is also a great choice if you’re using continuous integration server Jenkins.

Updated to include –coverage-html. Thanks kmmbvnr!

Note: I’ve had trouble running debugger pdb / pudb in a unit test started from jtest. Using just ‘test’ works fine.

2 Comments »

  1. graham said,

    May 11, 2012 at 18:00

    @kmmbvnr That’s fantastic, thanks!

  2. kmmbvnr said,

    May 5, 2012 at 06:13

    Just committed to django-jenkins

    Now you could generate coverage by starting jtest with --coverage-html-report=<dir_name> option

Leave a Comment

Note: Your comment will only appear on the site once I approve it manually. This can take a day or two. Thanks for taking the time to comment.