-
Notifications
You must be signed in to change notification settings - Fork 0
/
ears.py
79 lines (65 loc) · 2.17 KB
/
ears.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
"""
ears.py : a simple unit testing library for teaching in the IPython Notebook.
ears.run() looks for all the functions defined in the calling stack frame
(hopefully the top level interpreter session) whose names begin with the
characters 'test_' and calls them in an undetermined order, collecting and
reporting results.
Usage:
import ears
def test_pass(): pass
def test_fail(): assert False, 'Error message'
def test_error(): 1/0 # zero division error
ears.run()
"""
import sys
import inspect
import traceback
def run(prefix='test_', verbose=False):
"""
Look for test functions defined by caller, execute, and report.
"""
# Collect functions defined in calling context.
caller_defs = inspect.stack()[1][0].f_globals
test_functions = dict([(n, caller_defs[n]) for n in caller_defs
if n.startswith(prefix) and callable(caller_defs[n])])
setup = caller_defs.get('setup', None)
teardown = caller_defs.get('teardown', None)
# Execute and record.
passes = []
fails = []
errors = []
for (name, test) in test_functions.iteritems():
if verbose:
print name
if setup is not None:
setup()
try:
test()
passes.append((name, None))
sys.stdout.write('.')
except AssertionError as e:
fails.append((name, traceback.format_exc()))
sys.stdout.write('f')
except Exception as e:
errors.append((name, traceback.format_exc()))
sys.stdout.write('E')
if teardown is not None:
teardown()
# Report.
print
print '{0} pass, {1} fail, {2} error'.format(len(passes),
len(fails),
len(errors))
for (title, group) in (('fail', fails),
('error', errors)):
for (name, exc) in group:
print '{0}\n{1}: {2}'.format('-'*40, title, name)
print exc
if __name__ == '__main__':
def test_pass():
pass
def test_fail():
assert False, 'Error message'
def test_error():
1/0
run()