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
|
import traceback
from nose.plugins import Plugin
from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
class MarkdownSyntaxError(Exception):
pass
class Markdown(ErrorClassPlugin):
""" Add MarkdownSyntaxError and ensure proper formatting. """
mdsyntax = ErrorClass(
MarkdownSyntaxError,
label='MarkdownSyntaxError',
isfailure=True
)
enabled = True
def configure(self, options, conf):
self.conf = conf
def addError(self, test, err):
""" Ensure other plugins see the error by returning nothing here. """
pass
def formatError(self, test, err):
""" Remove unnessecary and unhelpful traceback from error report. """
et, ev, tb = err
if et.__name__ == 'MarkdownSyntaxError':
return et, ev, ''
return err
def escape(html):
""" Escape HTML for display as source within HTML. """
html = html.replace('&', '&')
html = html.replace('<', '<')
html = html.replace('>', '>')
return html
class HtmlOutput(Plugin):
"""Output test results as ugly, unstyled html. """
name = 'html-output'
score = 2 # run late
enabled = True
def __init__(self):
super(HtmlOutput, self).__init__()
self.html = [
'<html><head>',
'<title>Test output</title>',
'</head><body>'
]
def configure(self, options, conf):
self.conf = conf
def addSuccess(self, test):
self.html.append('<span>ok</span>')
def addError(self, test, err):
err = self.formatErr(err)
self.html.append('<span>ERROR</span>')
self.html.append('<pre>%s</pre>' % escape(err))
def addFailure(self, test, err):
err = self.formatErr(err)
self.html.append('<span>FAIL</span>')
self.html.append('<pre>%s</pre>' % escape(err))
def finalize(self, result):
self.html.append('<div>')
self.html.append(
"Ran %d test%s" %
(result.testsRun, result.testsRun != 1 and "s" or "")
)
self.html.append('</div>')
self.html.append('<div>')
if not result.wasSuccessful():
self.html.extend(['<span>FAILED (',
'failures=%d ' % len(result.failures),
'errors=%d' % len(result.errors)])
for cls in list(result.errorClasses.keys()):
storage, label, isfail = result.errorClasses[cls]
if len(storage):
self.html.append(' %ss=%d' % (label, len(storage)))
self.html.append(')</span>')
else:
self.html.append('OK')
self.html.append('</div></body></html>')
f = open('test-output.html', 'w')
for l in self.html:
f.write(l)
f.close()
def formatErr(self, err):
exctype, value, tb = err
if not isinstance(value, exctype):
value = exctype(value)
return ''.join(traceback.format_exception(exctype, value, tb))
def startContext(self, ctx):
try:
n = ctx.__name__
except AttributeError:
n = str(ctx).replace('<', '').replace('>', '')
self.html.extend(['<fieldset>', '<legend>', n, '</legend>'])
try:
path = ctx.__file__.replace('.pyc', '.py')
self.html.extend(['<div>', path, '</div>'])
except AttributeError:
pass
def stopContext(self, ctx):
self.html.append('</fieldset>')
def startTest(self, test):
self.html.extend([
'<div><span>',
test.shortDescription() or str(test),
'</span>'
])
def stopTest(self, test):
self.html.append('</div>')
|