Graham King

Solvitas perambulum

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

Summary
To achieve unit test code coverage in Python and Django, use the `coverage` package by installing it and running your tests with coverage commands, then generating an HTML report. Django's default test runner runs tests for all apps, including third-party ones, which can be avoided using `django-jenkins`. Install `django-jenkins`, update your `settings.py` to specify only your project's apps, and then run tests with `jtest` to get a coverage report for just your apps. Note that older `django-jenkins` versions lack the `--coverage-html` option, necessitating manual coverage commands. Additionally, `django-jenkins` is beneficial for those using Jenkins CI but has issues with debuggers in unit tests using `jtest`.

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.