from django.test.simple import DjangoTestSuiteRunner from django.conf import settings from django.core.urlresolvers import resolve, get_resolver IGNORED_COVERAGE_URLS = getattr(settings, 'IGNORED_COVERAGE_URLS', []) def get_configured_url_names(urllist=None): """Recurses through django url resolvers to get a full list of all url names""" if urllist is None: urllist = get_resolver(None).url_patterns unique_names = set() for entry in urllist: name = getattr(entry, 'name', None) if entry.regex.pattern in IGNORED_COVERAGE_URLS: continue if name is not None: unique_names.add(name) if hasattr(entry, 'url_patterns'): unique_names.update(get_configured_url_names(entry.url_patterns)) return unique_names unique_url_names = set() class UrlMiddlewareLogger(object): def process_request(self, request): unique_url_names.add(resolve(request.path).url_name) class CustomTestRunner(DjangoTestSuiteRunner): def __init__(self, *args, **kwargs): super(CustomTestRunner, self).__init__(*args, **kwargs) def run_tests(self, test_labels, **kwargs): # setup custom middleware class that records urls accessed orig_middleware = getattr(settings, 'MIDDLEWARE_CLASSES', []) middleware = tuple(list(orig_middleware) + [__name__ + '.UrlMiddlewareLogger']) setattr(settings, 'MIDDLEWARE_CLASSES', middleware) test_results = super(CustomTestRunner, self).run_tests(test_labels, **kwargs) # reset middleware back to what it was setattr(settings, 'MIDDLEWARE_CLASSES', orig_middleware) configured_names = get_configured_url_names() missed_names = sorted(configured_names.difference(unique_url_names)) hit_names = configured_names.intersection(unique_url_names) print '-----------------------------------------------------' print 'Status: %d of %d URLs hit in test suite' % (len(hit_names), len(configured_names)) print '-----------------------------------------------------' if len(missed_names) > 0: print 'URL Names in URL Configuration not hit in test suite:' print '-----------------------------------------------------' for missed_name in missed_names: print ' ' + missed_name print return test_results