forked from willhardy/django-seo
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathtest-coverage.py
More file actions
executable file
·156 lines (119 loc) · 5.56 KB
/
Copy pathtest-coverage.py
File metadata and controls
executable file
·156 lines (119 loc) · 5.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python
"""
Run Django Tests with full test coverage
This starts coverage early enough to get all of the model loading &
other startup code. It also allows you to change the output location
from $PROJECT_ROOT/coverage by setting the $TEST_COVERAGE_OUTPUT_DIR
environmental variable.
This is a customised version of the django coverage tool by acdha,
downloaded from http://gist.github.com/288810
Modified by Will Hardy (will@hardysoftware.de) June 2010.
"""
import logging
import os
import sys
from coverage import coverage
def main():
PROJECT_ROOT = os.path.realpath(os.path.join(os.path.dirname(__file__), ".."))
output_dir = os.environ.get("TEST_COVERAGE_OUTPUT_DIR", os.path.join(PROJECT_ROOT, "coverage"))
if 'DJANGO_SETTINGS_MODULE' not in os.environ:
import settings as sett
os.environ["DJANGO_SETTINGS_MODULE"] = sett.__name__
print >>sys.stderr, "Test coverage output will be stored in %s" % output_dir
if not os.path.exists(output_dir):
os.mkdir(output_dir)
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s: %(message)s', filename=os.path.join(output_dir, "tests.log"))
from django.conf import settings
# Start code coverage before anything else if necessary
use_coverage = hasattr(settings, 'COVERAGE_MODULES') and len(settings.COVERAGE_MODULES)
if use_coverage:
if len(sys.argv) > 1 and sys.argv[1] == "--branch":
sys.argv.pop(1)
cov = coverage(branch=True) # Enable super experimental branch support
else:
cov = coverage()
cov.use_cache(0) # Do not cache any of the coverage.py stuff
cov.exclude('^\s*$') # Exclude empty lines
cov.exclude('^\s*#.*$') # Exclude comment blocks
cov.exclude('^\s*(import|from)\s') # Exclude import statements
cov.start()
from django.conf import settings
from django.db.models import get_app, get_apps
# NOTE: Normally we'd use ``django.core.management.commands.test`` here but
# we want to have South's intelligence for applying database migrations or
# syncing everything directly (based on ``settings.SOUTH_TESTS_MIGRATE``).
# South's test Command is a subclass of the standard Django test Command so
# it's otherwise identical:
try:
from south.management.commands import test
except ImportError:
from django.core.management.commands import test
# Suppress debugging displays, etc. to test as real users will see it:
settings.DEBUG = False
settings.TEMPLATE_DEBUG = False
# This avoids things being cached when we attempt to regenerate them.
settings.CACHE_BACKEND = 'dummy:///'
# According to http://docs.djangoproject.com/en/1.0/topics/cache/#order-of-middleware-classes
# this should not be ahead of UpdateCacheMiddleware but to avoid this unresolved Django bug
# http://code.djangoproject.com/ticket/5176 we have to place SessionMiddleware first to avoid
# failures:
mc = list(settings.MIDDLEWARE_CLASSES)
try:
mc.remove('django.middleware.cache.FetchFromCacheMiddleware')
mc.remove('django.middleware.cache.UpdateCacheMiddleware')
except ValueError:
pass
settings.MIDDLEWARE_CLASSES = tuple(mc)
# If the user provided modules on the command-line we'll only test the
# listed modules. Otherwise we'll build a list of installed applications
# which we wrote and pretend the user entered that on the command-line
# instead.
test_labels = [ i for i in sys.argv[1:] if not i[0] == "-"]
if not test_labels:
test_labels = []
site_name = settings.SETTINGS_MODULE.split(".")[0]
for app in get_apps():
pkg = app.__package__ or app.__name__.replace(".models", "")
if pkg in settings.COVERAGE_MODULES:
test_labels.append(pkg)
else:
print >>sys.stderr, "Skipping tests for %s" % pkg
test_labels.sort()
print >>sys.stderr, "Automatically generated test labels for %s: %s" % (site_name, ", ".join(test_labels))
sys.argv.extend(test_labels)
settings.DEBUG = False
settings.TEMPLATE_DEBUG = False
command = test.Command()
rc = 0
sys.argv.insert(1, "test")
try:
command.run_from_argv(sys.argv)
except SystemExit, e:
rc = e.code
# Stop code coverage after tests have completed
if use_coverage:
cov.stop()
coverage_modules = filter(None, [
sys.modules[k] for k in sys.modules if any(
l for l in [ l.split(".")[0] for l in test_labels]
# Avoid issues with an empty models.py causing __package__ == None
if k.startswith(get_app(l).__package__ or get_app(l).__name__.replace(".models", ""))
)
])
if use_coverage:
# Print code metrics header
print ''
print '-------------------------------------------------------------------------'
print ' Unit Test Code Coverage Results'
print '-------------------------------------------------------------------------'
# Report code coverage metrics
cov.report(coverage_modules)
cov.html_report(coverage_modules, directory=output_dir)
cov.xml_report(coverage_modules, outfile=os.path.join(output_dir, "coverage.xml"))
# Print code metrics footer
print '-------------------------------------------------------------------------'
if rc != 0:
print >>sys.stderr, "Coverage report is not be accurate due to non-zero exit status: %d" % rc
sys.exit(rc)
if __name__ == "__main__":
main()