-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathautotest.py
executable file
·130 lines (111 loc) · 4.02 KB
/
autotest.py
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
#!/usr/bin/python
"""
This is a very hackish one-off inotify program that waits for python
files to be modified, and then runs the test suite.
If the test suite passes, it then re-runs it under a statement coverage
analyzer.
All results, in addition to being displayed to the terminal, are sent as
notifications to the desktop GUI.
"""
import os
import sys
from subprocess import call
import gtk
import pynotify # Display notifications
import pyinotify # Filesystem event monitoring
import coverage
app_name = 'Yardbird'
pynotify.init("%s Tests" % app_name)
def run_tests():
num_failed = call(['./manage.py', 'test'], cwd='example')
if num_failed:
notify_tests_failed(num_failed)
return False
return True
def generate_coverage():
try:
os.unlink('./example/.coverage')
except OSError:
pass
num_failed = call(['python', '../coverage.py', '-x', './manage.py', 'test'], cwd='example')
reload(coverage)
cov = coverage.the_coverage
cov.use_cache(True, cache_file='./example/.coverage')
cov.get_ready()
return cov
def coverage_report(cov):
morfs = [morf for morf in cov.filter_by_prefix(cov.cexecuted.keys(),
omit_prefixes=['/usr', '<doctest', 'coverage', 'autotest']) if
'<doctest' not in cov.morf_name(morf)]
morfs.sort(cov.morf_name_compare)
report = {}
total_statements = 0
total_tested = 0
for morf in morfs:
_, statements, missing, readable = cov.analysis(morf)
num_statements = len(statements)
if not num_statements:
continue
total_statements += num_statements
num_tested = num_statements - len(missing)
total_tested += num_tested
if num_tested < num_statements:
report[cov.morf_name(morf)] = (num_statements, num_tested,
str(readable))
if total_tested < total_statements:
percentage = 100.0 * total_tested / total_statements
notify_incomplete_coverage(percentage, report)
else:
notify_complete_coverage()
return report
def notify_tests_failed(num_failed):
notification = pynotify.Notification('%s Test Failure' % app_name,
'%d tests failed' % num_failed, gtk.STOCK_DIALOG_ERROR)
notification.set_urgency(pynotify.URGENCY_LOW)
notification.show()
def notify_tests_passed():
notification = pynotify.Notification('%s Tests Passed' % app_name,
'All tests successfully ran',
gtk.STOCK_DIALOG_INFO)
notification.set_urgency(pynotify.URGENCY_LOW)
notification.show()
def notify_incomplete_coverage(coverage, stats):
report = ''
for filename, vals in stats.iteritems():
total, tested, lines = vals
if report:
report += '\n'
report += '%d%% %s %s' % (100.0 * tested / total, filename,
lines)
title = '%s Test Coverage %d%%' % (app_name, coverage)
print '\n', title
print '=' * len(title)
print report
notification = pynotify.Notification(title, report,
gtk.STOCK_DIALOG_WARNING)
notification.set_urgency(pynotify.URGENCY_LOW)
notification.show()
def notify_complete_coverage():
notification = pynotify.Notification('%s Test Coverage Complete' %
app_name, 'Your tests have 100% statement coverage!\n' +
'Now comes the hard part.', gtk.STOCK_DIALOG_INFO)
notification.set_urgency(pynotify.URGENCY_LOW)
notification.show()
class SourceChanged(pyinotify.ProcessEvent):
def process_IN_MODIFY(self, event):
if not event.pathname.endswith('.py'):
return
if run_tests():
notify_tests_passed()
coverage_report(generate_coverage())
def autorun_tests():
wm = pyinotify.WatchManager()
handler = SourceChanged()
notifier = pyinotify.Notifier(wm, default_proc_fun=handler)
wm.add_watch(os.getcwd(), pyinotify.IN_MODIFY, rec=True, auto_add=True)
notifier.loop()
if __name__ == '__main__':
if run_tests():
notify_tests_passed()
coverage_report(generate_coverage())
autorun_tests()