How to test coverage properly with Django + Nose

At the moment it's not possible to accurately run coverage alongside with django-nose (because of the way Django 1.7 loads models). So to get the coverage stats, you need to use coverage.py directly from command line, e.g:

$ coverage run --branch --source=app1,app2 ./manage.py test
$ coverage report
$ coverage html -d coverage-report

You can put coverage.py settings into .coveragerc file in the project root (the same dir as manage.py).

This issue is reported on django-nose GitHub page: https://github.com/django-nose/django-nose/issues/180 so maintainers know about the problem, you can let them know that you're also experiencing this issue.

UPDATE

eliangcs pointed out (django-nose issues on GiHub), that woraround is to modify your manage.py:

import os
import sys

if __name__ == "__main__":
    # ...
    from django.core.management import execute_from_command_line

    is_testing = 'test' in sys.argv

    if is_testing:
        import coverage
        cov = coverage.coverage(source=['package1', 'package2'], omit=['*/tests/*'])
        cov.erase()
        cov.start()

    execute_from_command_line(sys.argv)

    if is_testing:
        cov.stop()
        cov.save()
        cov.report()

It works, but it's rather "hacky" approach.

UPDATE 2

I recommend for everybody that uses nose to have a look at py.test (http://pytest.org/), which is really good Python testing tool, it integrates well with Django, has a lot of plugins and many more. I was using django-nose, but tried py.test and never looked back.


As the docs say, "use the command line to run your program with coverage":

coverage run --branch --source=notify ./manage.py test