Resurrect URL coverage making it work with all tests, and move it to the test runner together with the template coverage report

- Legacy-Id: 6844
This commit is contained in:
Ole Laursen 2013-12-07 19:31:32 +00:00
parent 56f36018a2
commit 3053bef4cc
2 changed files with 92 additions and 94 deletions

View file

@ -101,98 +101,9 @@ class RedirectsTests(TestCase):
location = location[17:]
self.assertEqual(location, dst, (src, dst, location))
def get_patterns(module):
all = []
try:
patterns = module.urlpatterns
except AttributeError:
patterns = []
for item in patterns:
try:
subpatterns = get_patterns(item.urlconf_module)
except:
subpatterns = [""]
for sub in subpatterns:
if not sub:
all.append(item.regex.pattern)
elif sub.startswith("^"):
all.append(item.regex.pattern + sub[1:])
else:
all.append(item.regex.pattern + ".*" + sub)
return all
class UrlCoverageTestCase(unittest.TestCase):
def testUrlCoverage(self):
print " Testing testurl.list coverage"
testtuples = []
for root, dirs, files in os.walk(settings.BASE_DIR):
if "testurl.list" in files:
testtuples += read_testurls(root+"/testurl.list")
patterns = get_patterns(ietf.urls)
covered = []
for codes, testurl, goodurl in testtuples:
for pattern in patterns:
if re.match(pattern, testurl[1:]):
covered.append(pattern)
if not set(patterns) == set(covered):
missing = list(set(patterns) - set(covered))
print "The following URLs are not tested by any testurl.list"
for pattern in missing:
if not pattern[1:].split("/")[0] in [ "admin", "accounts" ]:
print " NoTest", pattern
print ""
else:
print "All URLs are included in some testurl.list"
class MainUrlTests(TestCase):
def test_urls(self):
self.assertEqual(self.client.get("/_doesnotexist/").status_code, 404)
self.assertEqual(self.client.get("/sitemap.xml").status_code, 200)
# Google webmaster tool verification page
self.assertEqual(self.client.get("/googlea30ad1dacffb5e5b.html").status_code, 200)
def get_templates():
templates = set()
# Shoud we teach this to use TEMPLATE_DIRS?
templatepath = os.path.join(settings.BASE_DIR,"templates")
for root, dirs, files in os.walk(templatepath):
if ".svn" in dirs:
dirs.remove(".svn")
relative_path = root[len(templatepath)+1:]
for file in files:
if file.endswith("~") or file.startswith("#"):
continue
if relative_path == "":
templates.add(file)
else:
templates.add(os.path.join(relative_path, file))
return templates
class TemplateCoverageTestCase(unittest.TestCase):
def testTemplateCoverage(self):
if not test_runner.loaded_templates:
print " Skipping template coverage test"
return
print " Testing template coverage"
all_templates = get_templates()
#notexist = list(test_runner.loaded_templates - all_templates)
#if notexist:
# notexist.sort()
# print "The following templates do not exist"
# for x in notexist:
# print "NotExist", x
notloaded = list(all_templates - test_runner.loaded_templates)
if notloaded:
notloaded.sort()
print "The following templates were never loaded during test"
for x in notloaded:
print " NotLoaded", x
else:
print " All templates were loaded during test"

View file

@ -32,7 +32,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import socket
import socket, re, os
from django.conf import settings
from django.template import TemplateDoesNotExist
@ -44,6 +44,7 @@ import debug
import ietf.utils.mail
loaded_templates = set()
visited_urls = set()
test_database_name = None
old_destroy = None
old_create = None
@ -74,6 +75,77 @@ def template_coverage_loader(template_name, dirs):
template_coverage_loader.is_usable = True
class RecordUrlsMiddleware(object):
def process_request(self, request):
visited_urls.add(request.path)
def get_patterns(module):
all = []
try:
patterns = module.urlpatterns
except AttributeError:
patterns = []
for item in patterns:
try:
subpatterns = get_patterns(item.urlconf_module)
except:
subpatterns = [""]
for sub in subpatterns:
if not sub:
all.append(item.regex.pattern)
elif sub.startswith("^"):
all.append(item.regex.pattern + sub[1:])
else:
all.append(item.regex.pattern + ".*" + sub)
return all
def check_url_coverage():
patterns = get_patterns(ietf.urls)
IGNORED_PATTERNS = ("admin",)
patterns = [(p, re.compile(p)) for p in patterns if p[1:].split("/")[0] not in IGNORED_PATTERNS]
covered = set()
for url in visited_urls:
for pattern, compiled in patterns:
if pattern not in covered and compiled.match(url[1:]): # strip leading /
covered.add(pattern)
break
missing = list(set(p for p, compiled in patterns) - covered)
if missing:
print "The following URL patterns were not tested"
for pattern in sorted(missing):
print " Not tested", pattern
def get_templates():
templates = set()
# Should we teach this to use TEMPLATE_DIRS?
templatepath = os.path.join(settings.BASE_DIR, "templates")
for root, dirs, files in os.walk(templatepath):
if ".svn" in dirs:
dirs.remove(".svn")
relative_path = root[len(templatepath)+1:]
for file in files:
if file.endswith("~") or file.startswith("#"):
continue
if relative_path == "":
templates.add(file)
else:
templates.add(os.path.join(relative_path, file))
return templates
def check_template_coverage():
all_templates = get_templates()
not_loaded = list(all_templates - loaded_templates)
if not_loaded:
print "The following templates were never loaded during test"
for t in sorted(not_loaded):
print " Not loaded", t
def run_tests_1(test_labels, *args, **kwargs):
global old_destroy, old_create, test_database_name
from django.db import connection
@ -81,18 +153,33 @@ def run_tests_1(test_labels, *args, **kwargs):
connection.creation.__class__.create_test_db = safe_create_1
old_destroy = connection.creation.__class__.destroy_test_db
connection.creation.__class__.destroy_test_db = safe_destroy_0_1
if not test_labels:
check_coverage = not test_labels
if check_coverage:
settings.TEMPLATE_LOADERS = ('ietf.utils.test_runner.template_coverage_loader',) + settings.TEMPLATE_LOADERS
test_labels = [x.split(".")[-1] for x in settings.INSTALLED_APPS if x.startswith("ietf")] + ['redirects.TemplateCoverageTestCase',]
settings.MIDDLEWARE_CLASSES = ('ietf.utils.test_runner.RecordUrlsMiddleware',) + settings.MIDDLEWARE_CLASSES
if not test_labels:
test_labels = [x.split(".")[-1] for x in settings.INSTALLED_APPS if x.startswith("ietf")]
if settings.SITE_ID != 1:
print " Changing SITE_ID to '1' during testing."
settings.SITE_ID = 1
if settings.TEMPLATE_STRING_IF_INVALID != '':
print " Changing TEMPLATE_STRING_IF_INVALID to '' during testing."
settings.TEMPLATE_STRING_IF_INVALID = ''
assert(not settings.IDTRACKER_BASE_URL.endswith('/'))
kwargs["verbosity"] = kwargs["verbosity"]
return django_run_tests(test_labels, *args, **kwargs)
results = django_run_tests(test_labels, *args, **kwargs)
if check_coverage:
check_url_coverage()
check_template_coverage()
return results
def run_tests(*args, **kwargs):
# Tests that involve switching back and forth between the real