import os, shutil, sys, unittest
# Look for coverage.py in __file__/lib as well as sys.path
sys.path = [os.path.join(os.path.dirname(__file__), "lib")] + sys.path
from coverage import coverage
from inspect import getmembers, ismodule
from django.test.simple import run_tests as django_test_runner
from django.conf import settings
def get_all_coverage_modules(module_path):
"""
Returns all possible modules to report coverage on, even if they
aren't loaded.
"""
app_path = module_path.split('.')
app_package = __import__(module_path, {}, {}, app_path[-1])
app_dirpath = app_package.__path__[-1]
mod_list = []
for root, dirs, files in os.walk(app_dirpath):
root_path = app_path + root[len(app_dirpath):].split(os.path.sep)[1:]
for file in files:
if file.lower().endswith('.py'):
mod_name = file[:-3].lower()
try:
mod = __import__('.'.join(root_path + [mod_name]), {}, {},
mod_name)
except ImportError:
pass
else:
mod_list.append(mod)
return mod_list
def test_runner_with_coverage(test_labels, verbosity=1, interactive=True, extra_tests=[]):
"""Custom test runner. Follows the django.test.simple.run_tests() interface."""
# Start code coverage before anything else if necessary
cov = None
if hasattr(settings, 'COVERAGE_MODULES'):
cov = coverage()
cov.use_cache(1) # Do not cache any of the coverage.py stuff
#cov.exclude('if __name__ == .__main__.:')
cov.start()
test_results = django_test_runner(test_labels, verbosity, interactive, extra_tests)
# Stop code coverage after tests have completed
if hasattr(settings, 'COVERAGE_MODULES'):
cov.stop()
# Print code metrics header
print ''
print '----------------------------------------------------------------------'
print ' Unit Test Code Coverage Results'
print '----------------------------------------------------------------------'
# Report code coverage metrics
if hasattr(settings, 'COVERAGE_MODULES'):
coverage_modules = []
for module in settings.COVERAGE_MODULES:
coverage_modules.extend(get_all_coverage_modules(module))
cov.report(coverage_modules, show_missing=1)
#cov.html_report(directory='covhtml')
#cov.combine()
cov.save()
# Print code metrics footer
print '----------------------------------------------------------------------'
return test_results