Skip to content

Instantly share code, notes, and snippets.

@coderanger
Created May 7, 2010 20:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coderanger/393973 to your computer and use it in GitHub Desktop.
Save coderanger/393973 to your computer and use it in GitHub Desktop.
A Django command to generate a test coverage report
from __future__ import absolute_import
import os
import sys
import webbrowser
from django.conf import settings
from django.core.management import setup_environ
from django.core.management.commands import test
from django.utils.importlib import import_module
from django.db.models.loading import cache
class Command(test.Command):
help = test.Command.help.rstrip('.') + ' and create a coverage report.'
def handle(self, *test_labels, **options):
import coverage
cov = coverage.coverage(cover_pylib=False, branch=True)
cov.use_cache(False)
cov.start()
base_mod = os.environ['DJANGO_SETTINGS_MODULE'].split('.', 1)[0]
to_import = []
for n, m in sys.modules.items():
if base_mod in n and m is not None and hasattr(m, '__file__') and os.path.dirname(m.__file__) != os.path.dirname(__file__):
del sys.modules[n]
to_import.append(n)
for app_label, model_dict in cache.app_models.items():
for model_name, model in model_dict.items():
if model.__module__ in to_import:
del model_dict[model_name]
for n in to_import:
sys.modules[n] = import_module(n)
proj_dir = setup_environ(import_module(os.environ['DJANGO_SETTINGS_MODULE']))
try:
result = super(Command, self).handle(*test_labels, **options)
finally:
cov.stop()
modules = [m for _, m in sys.modules.items()
if m is not None and hasattr(m, '__file__')
and os.path.splitext(m.__file__)[-1] in ('.py', '.pyc')
and m.__file__.startswith(proj_dir)
and m.__file__ != __file__]
self._report(cov, modules)
return result
def _report(self, cov, modules):
if hasattr(settings, 'TEST_COVERAGE_OUTPUT'):
html_dir = os.path.join(os.path.dirname(settings.TEST_COVERAGE_OUTPUT), 'coverage_html')
else:
html_dir = os.path.join(proj_dir, 'build', 'coverage_html')
if not os.path.exists(html_dir):
os.makedirs(html_dir)
cov.html_report(modules, html_dir)
webbrowser.open_new_tab('file://'+html_dir+'/index.html')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment