报告效果如下:
HTMLTestRunner脚本代码如下:
#coding=utf-8 # URL: http://tungwaiyip.info/software/HTMLTestRunner.html __author__ = "Wai Yip Tung, Findyou" __version__ = "0.8.2.1" """ Version 0.8.2.1 -Findyou * 支持中文,汉化 * 调整样式,美化(需要连入网络,使用的百度的Bootstrap.js) * 增加 通过分类显示、测试人员、通过率的展示 * 优化“详细”与“收起”状态的变换 * 增加返回顶部的锚点 """ import datetime import io import sys import time import unittest from xml.sax import saxutils import sys #reload(sys) #sys.setdefaultencoding('utf-8') class OutputRedirector(object): def __init__(self, fp): self.fp = fp def write(self, s): self.fp.write(s) def writelines(self, lines): self.fp.writelines(lines) def flush(self): self.fp.flush() stdout_redirector = OutputRedirector(sys.stdout) stderr_redirector = OutputRedirector(sys.stderr) class Template_mixin(object): """ Overall structure of an HTML report HTML +------------------------+ | | | | | | | STYLESHEET | | +----------------+ | | | | | | +----------------+ | | | | | | | | | | | | HEADING | | +----------------+ | | | | | | +----------------+ | | | | REPORT | | +----------------+ | | | | | | +----------------+ | | | | ENDING | | +----------------+ | | | | | | +----------------+ | | | | | | | +------------------------+ """ STATUS = { 0: '通过', 1: '失败', 2: '错误', } # 默认测试标题 DEFAULT_TITLE = '接口自动化测试报告' DEFAULT_DESCRIPTION = '' # 默认测试人员 DEFAULT_TESTER = 'Agoly' # ------------------------------------------------------------------------ # HTML Template HTML_TMPL = r"""%(title)s %(stylesheet)s %(heading)s %(report)s %(ending)s """ # variables: (title, generator, stylesheet, heading, report, ending) STYLESHEET_TMPL = """ """ # ------------------------------------------------------------------------ # Heading # #面板标题
HEADING_TMPL = """%(title)s
%(parameters)s%(description)s""" # variables: (title, parameters, description) HEADING_ATTRIBUTE_TMPL = """%(name)s : %(value)s
""" # variables: (name, value) # ------------------------------------------------------------------------ # Report # # 汉化,加美化效果 --Findyou REPORT_TMPL = """通过率【%(passrate)s】 失败【%(fail)s】 成功【%(Pass)s】 所有【%(count)s】
""" # variables: (test_list, count, Pass, fail, error ,passrate) REPORT_CLASS_TMPL = r"""
%(test_list)s 用例集/测试用例 总计 通过 失败 错误 详细 总计 %(count)s %(Pass)s %(fail)s %(error)s 通过率:%(passrate)s """ # variables: (style, desc, count, Pass, fail, error, cid) #失败 的样式,去掉原来JS效果,美化展示效果 -Findyou REPORT_TEST_WITH_OUTPUT_TMPL = r""" %(desc)s %(count)s %(Pass)s %(fail)s %(error)s 详细 """ # variables: (tid, Class, style, desc, status) %(desc)s %(script)s# 通过 的样式,加标签效果 -Findyou
#REPORT_TEST_NO_OUTPUT_TMPL = r"""
#
# %(desc)s
#%(status)s
## 通过 的样式,加标签效果 -Findyou
REPORT_TEST_NO_OUTPUT_TMPL=r""" %(desc)s
%(script)s""" # variables: (tid, Class, style, desc, status)
REPORT_TEST_OUTPUT_TMPL = r"""
%(output)s
""" # variables: (id, output)# ------------------------------------------------------------------------
# ENDING
#
# 增加返回顶部按钮 --Findyou
ENDING_TMPL = """"""# -------------------- The end of the Template class -------------------
TestResult = unittest.TestResult
class _TestResult(TestResult):
# note: _TestResult is a pure representation of results.
# It lacks the output and reporting ability compares to unittest._TextTestResult.def __init__(self, verbosity=1):
TestResult.__init__(self)
self.stdout0 = None
self.stderr0 = None
self.success_count = 0
self.failure_count = 0
self.error_count = 0
self.verbosity = verbosity# result is a list of result in 4 tuple
# (
# result code (0: success; 1: fail; 2: error),
# TestCase object,
# Test output (byte string),
# stack trace,
# )
self.result = []
#增加一个测试通过率 --Findyou
self.passrate=float(0)def startTest(self, test):
TestResult.startTest(self, test)
# just one buffer for both stdout and stderr
self.outputBuffer = io.StringIO()
stdout_redirector.fp = self.outputBuffer
stderr_redirector.fp = self.outputBuffer
self.stdout0 = sys.stdout
self.stderr0 = sys.stderr
sys.stdout = stdout_redirector
sys.stderr = stderr_redirectordef complete_output(self):
"""
Disconnect output redirection and return buffer.Safe to call multiple times.
"""
if self.stdout0:
sys.stdout = self.stdout0
sys.stderr = self.stderr0
self.stdout0 = None
self.stderr0 = None
return self.outputBuffer.getvalue()def stopTest(self, test):
# Usually one of addSuccess, addError or addFailure would have been called.
# But there are some path in unittest that would bypass this.
# We must disconnect stdout in stopTest(), which is guaranteed to be called.
self.complete_output()def addSuccess(self, test):
self.success_count += 1
TestResult.addSuccess(self, test)
output = self.complete_output()
self.result.append((0, test, output, ''))
if self.verbosity > 1:
sys.stderr.write('ok ')
sys.stderr.write(str(test))
sys.stderr.write('\n')
else:
sys.stderr.write('.')def addError(self, test, err):
self.error_count += 1
TestResult.addError(self, test, err)
_, _exc_str = self.errors[-1]
output = self.complete_output()
self.result.append((2, test, output, _exc_str))
if self.verbosity > 1:
sys.stderr.write('E ')
sys.stderr.write(str(test))
sys.stderr.write('\n')
else:
sys.stderr.write('E')def addFailure(self, test, err):
self.failure_count += 1
TestResult.addFailure(self, test, err)
_, _exc_str = self.failures[-1]
output = self.complete_output()
self.result.append((1, test, output, _exc_str))
if self.verbosity > 1:
sys.stderr.write('F ')
sys.stderr.write(str(test))
sys.stderr.write('\n')
else:
sys.stderr.write('F')class HTMLTestRunner(Template_mixin):
"""
"""
def __init__(self, stream=sys.stdout, verbosity=1,title=None,description=None,tester=None):
self.stream = stream
self.verbosity = verbosity
if title is None:
self.title = self.DEFAULT_TITLE
else:
self.title = title
if description is None:
self.description = self.DEFAULT_DESCRIPTION
else:
self.description = description
if tester is None:
self.tester = self.DEFAULT_TESTER
else:
self.tester = testerself.startTime = datetime.datetime.now()
def run(self, test):
"Run the given test case or test suite."
result = _TestResult(self.verbosity)
test(result)
self.stopTime = datetime.datetime.now()
self.generateReport(test, result)
#print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
print('\nTime Elapsed: %s' % (self.stopTime - self.startTime), file=sys.stderr)
return resultdef sortResult(self, result_list):
# unittest does not seems to run in any particular order.
# Here at least we want to group them together by class.
rmap = {}
classes = []
for n,t,o,e in result_list:
cls = t.__class__
if not cls in rmap:
rmap[cls] = []
classes.append(cls)
rmap[cls].append((n,t,o,e))
r = [(cls, rmap[cls]) for cls in classes]
return r#替换测试结果status为通过率 --Findyou
def getReportAttributes(self, result):
"""
Return report attributes as a list of (name, value).Override this to add custom attributes.
"""
startTime = str(self.startTime)[:19]
duration = str(self.stopTime - self.startTime)[:10]
status = []
status.append('【总共:%s】' % (result.success_count + result.failure_count + result.error_count))
if result.success_count:
status.append('【通过:%s】' % result.success_count)
if result.failure_count:
status.append('【失败:%s】' % result.failure_count)
if result.error_count:
status.append('【错误:%s】' % result.error_count)
if status:
status = ' '.join(status)
try:
self.passrate = str("%.2f%%" % (float(result.success_count) / float(result.success_count + result.failure_count + result.error_count) * 100))
except ZeroDivisionError:
self.passrate = 0
else:
status = 'none'
print(status)
return [
(u'测试人员', self.tester),
(u'开始时间',startTime),
(u'合计耗时',duration),
('测试结果',status + "【通过率= "+self.passrate+'】'),
]def generateReport(self, test, result):
report_attrs = self.getReportAttributes(result)
generator = 'HTMLTestRunner %s' % __version__
stylesheet = self._generate_stylesheet()
heading = self._generate_heading(report_attrs)
report = self._generate_report(result)
ending = self._generate_ending()
output = self.HTML_TMPL % dict(
title = saxutils.escape(self.title),
generator = generator,
stylesheet = stylesheet,
heading = heading,
report = report,
ending = ending,
)
self.stream.write(output.encode('utf8'))def _generate_stylesheet(self):
return self.STYLESHEET_TMPL#增加Tester显示 -Findyou
def _generate_heading(self, report_attrs):
a_lines = []
for name, value in report_attrs:
line = self.HEADING_ATTRIBUTE_TMPL % dict(
name = saxutils.escape(name),
value = saxutils.escape(value),
)
a_lines.append(line)
heading = self.HEADING_TMPL % dict(
title = saxutils.escape(self.title),
parameters = ''.join(a_lines),
description = saxutils.escape(self.description),
tester= saxutils.escape(self.tester),
)
return heading#生成报告 --Findyou添加注释
def _generate_report(self, result):
rows = []
sortedResult = self.sortResult(result.result)
for cid, (cls, cls_results) in enumerate(sortedResult):
# subtotal for a class
np = nf = ne = 0
for n,t,o,e in cls_results:
if n == 0: np += 1
elif n == 1: nf += 1
else: ne += 1# format class description
if cls.__module__ == "__main__":
name = cls.__name__
else:
name = "%s.%s" % (cls.__module__, cls.__name__)
doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
desc = doc and '%s: %s' % (name, doc) or namerow = self.REPORT_CLASS_TMPL % dict(
style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
desc = desc,
count = np+nf+ne,
Pass = np,
fail = nf,
error = ne,
cid = 'c%s' % (cid+1),
)
rows.append(row)for tid, (n,t,o,e) in enumerate(cls_results):
self._generate_report_test(rows, cid, tid, n, t, o, e)report = self.REPORT_TMPL % dict(
test_list = ''.join(rows),
count = str(result.success_count+result.failure_count+result.error_count),
Pass = str(result.success_count),
fail = str(result.failure_count),
error = str(result.error_count),
passrate =self.passrate,
)
return reportdef _generate_report_test(self, rows, cid, tid, n, t, o, e):
# e.g. 'pt1.1', 'ft1.1', etc
has_output = bool(o or e)
# ID修改点为下划线,支持Bootstrap折叠展开特效 - Findyou
tid = (n == 0 and 'p' or 'f') + 't%s_%s' % (cid+1,tid+1)
name = t.id().split('.')[-1]
doc = t.shortDescription() or ""
desc = doc and ('%s: %s' % (name, doc)) or name
tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL# utf-8 支持中文 - Findyou
# o and e should be byte string because they are collected from stdout and stderr?
if isinstance(o, str):
# TODO: some problem with 'string_escape': it escape \n and mess up formating
# uo = unicode(o.encode('string_escape'))
# uo = o.decode('latin-1')
uo = o
else:
uo = o
if isinstance(e, str):
# TODO: some problem with 'string_escape': it escape \n and mess up formating
# ue = unicode(e.encode('string_escape'))
# ue = e.decode('latin-1')
ue = e
else:
ue = escript = self.REPORT_TEST_OUTPUT_TMPL % dict(
# id = tid,
id = '',
output = saxutils.escape(uo+ue),
)row = tmpl % dict(
tid = tid,
Class = (n == 0 and 'hiddenRow' or 'none'),
style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'passCase'),
desc = desc,
script = script,
status = self.STATUS[n],
)
rows.append(row)
if not has_output:
returndef _generate_ending(self):
return self.ENDING_TMPL##############################################################################
# Facilities for running tests from the command line
############################################################################### Note: Reuse unittest.TestProgram to launch test. In the future we may
# build our own launcher to support more specific command line
# parameters like test title, CSS, etc.
class TestProgram(unittest.TestProgram):
"""
A variation of the unittest.TestProgram. Please refer to the base
class for command line parameters."""
def runTests(self):
# Pick HTMLTestRunner as the default test runner.
# base class's testRunner parameter is not useful because it means
# we have to instantiate HTMLTestRunner before we know self.verbosity.
if self.testRunner is None:
self.testRunner = HTMLTestRunner(verbosity=self.verbosity)
unittest.TestProgram.runTests(self)main = TestProgram
##############################################################################
# Executing this module from the command line
##############################################################################if __name__ == "__main__":
main(module=None)模板2:
#coding=utf-8 # URL: http://tungwaiyip.info/software/HTMLTestRunner.html __author__ = "Wai Yip Tung, Findyou" __version__ = "0.8.2.1" """ Version 0.8.2.1 -Findyou * 支持中文,汉化 * 调整样式,美化(需要连入网络,使用的百度的Bootstrap.js) * 增加 通过分类显示、测试人员、通过率的展示 * 优化“详细”与“收起”状态的变换 * 增加返回顶部的锚点 """ import datetime import io import sys import time import unittest from xml.sax import saxutils import sys #reload(sys) #sys.setdefaultencoding('utf-8') class OutputRedirector(object): def __init__(self, fp): self.fp = fp def write(self, s): self.fp.write(s) def writelines(self, lines): self.fp.writelines(lines) def flush(self): self.fp.flush() stdout_redirector = OutputRedirector(sys.stdout) stderr_redirector = OutputRedirector(sys.stderr) class Template_mixin(object): """ Overall structure of an HTML report HTML +------------------------+ | | | | | | | STYLESHEET | | +----------------+ | | | | | | +----------------+ | | | | | | | | | | | | HEADING | | +----------------+ | | | | | | +----------------+ | | | | REPORT | | +----------------+ | | | | | | +----------------+ | | | | ENDING | | +----------------+ | | | | | | +----------------+ | | | | | | | +------------------------+ """ STATUS = { 0: '通过', 1: '失败', 2: '错误', } # 默认测试标题 DEFAULT_TITLE = '接口自动化测试报告' DEFAULT_DESCRIPTION = '' # 默认测试人员 DEFAULT_TESTER = 'Agoly' # ------------------------------------------------------------------------ # HTML Template HTML_TMPL = r"""%(title)s %(stylesheet)s %(heading)s %(report)s %(ending)s %(chart_script)s """ # variables: (title, generator, stylesheet, heading, report, ending, chart_script) ECHARTS_SCRIPT = """ """ # variables: (title, generator, stylesheet, heading, report, ending) STYLESHEET_TMPL = """ """ # ------------------------------------------------------------------------ # Heading # #面板标题
HEADING_TMPL = """%(title)s
%(parameters)s%(description)s""" # variables: (title, parameters, description) HEADING_ATTRIBUTE_TMPL = """%(name)s : %(value)s
""" # variables: (name, value) # ------------------------------------------------------------------------ # Report # # 汉化,加美化效果 --Findyou REPORT_TMPL = """通过率【%(passrate)s】 失败【%(fail)s】 成功【%(Pass)s】 所有【%(count)s】
""" # variables: (test_list, count, Pass, fail, error ,passrate) REPORT_CLASS_TMPL = r"""
%(test_list)s 用例集/测试用例 总计 通过 失败 错误 详细 总计 %(count)s %(Pass)s %(fail)s %(error)s 通过率:%(passrate)s """ # variables: (style, desc, count, Pass, fail, error, cid) #失败 的样式,去掉原来JS效果,美化展示效果 -Findyou REPORT_TEST_WITH_OUTPUT_TMPL = r""" %(desc)s %(count)s %(Pass)s %(fail)s %(error)s 详细 """ # variables: (tid, Class, style, desc, status) %(desc)s %(script)s# 通过 的样式,加标签效果 -Findyou
#REPORT_TEST_NO_OUTPUT_TMPL = r"""
#
# %(desc)s
#%(status)s
## 通过 的样式,加标签效果 -Findyou
REPORT_TEST_NO_OUTPUT_TMPL=r""" %(desc)s
%(script)s""" # variables: (tid, Class, style, desc, status)
REPORT_TEST_OUTPUT_TMPL = r"""
%(output)s
""" # variables: (id, output)# ------------------------------------------------------------------------
# ENDING
#
# 增加返回顶部按钮 --Findyou
ENDING_TMPL = """"""# -------------------- The end of the Template class -------------------
TestResult = unittest.TestResult
class _TestResult(TestResult):
# note: _TestResult is a pure representation of results.
# It lacks the output and reporting ability compares to unittest._TextTestResult.def __init__(self, verbosity=1):
TestResult.__init__(self)
self.stdout0 = None
self.stderr0 = None
self.success_count = 0
self.failure_count = 0
self.error_count = 0
self.verbosity = verbosity# result is a list of result in 4 tuple
# (
# result code (0: success; 1: fail; 2: error),
# TestCase object,
# Test output (byte string),
# stack trace,
# )
self.result = []
#增加一个测试通过率 --Findyou
self.passrate=float(0)def startTest(self, test):
TestResult.startTest(self, test)
# just one buffer for both stdout and stderr
self.outputBuffer = io.StringIO()
stdout_redirector.fp = self.outputBuffer
stderr_redirector.fp = self.outputBuffer
self.stdout0 = sys.stdout
self.stderr0 = sys.stderr
sys.stdout = stdout_redirector
sys.stderr = stderr_redirectordef complete_output(self):
"""
Disconnect output redirection and return buffer.Safe to call multiple times.
"""
if self.stdout0:
sys.stdout = self.stdout0
sys.stderr = self.stderr0
self.stdout0 = None
self.stderr0 = None
return self.outputBuffer.getvalue()def stopTest(self, test):
# Usually one of addSuccess, addError or addFailure would have been called.
# But there are some path in unittest that would bypass this.
# We must disconnect stdout in stopTest(), which is guaranteed to be called.
self.complete_output()def addSuccess(self, test):
self.success_count += 1
TestResult.addSuccess(self, test)
output = self.complete_output()
self.result.append((0, test, output, ''))
if self.verbosity > 1:
sys.stderr.write('ok ')
sys.stderr.write(str(test))
sys.stderr.write('\n')
else:
sys.stderr.write('.')def addError(self, test, err):
self.error_count += 1
TestResult.addError(self, test, err)
_, _exc_str = self.errors[-1]
output = self.complete_output()
self.result.append((2, test, output, _exc_str))
if self.verbosity > 1:
sys.stderr.write('E ')
sys.stderr.write(str(test))
sys.stderr.write('\n')
else:
sys.stderr.write('E')def addFailure(self, test, err):
self.failure_count += 1
TestResult.addFailure(self, test, err)
_, _exc_str = self.failures[-1]
output = self.complete_output()
self.result.append((1, test, output, _exc_str))
if self.verbosity > 1:
sys.stderr.write('F ')
sys.stderr.write(str(test))
sys.stderr.write('\n')
else:
sys.stderr.write('F')class HTMLTestRunner(Template_mixin):
"""
"""
def __init__(self, stream=sys.stdout, verbosity=1,title=None,description=None,tester=None):
self.stream = stream
self.verbosity = verbosity
if title is None:
self.title = self.DEFAULT_TITLE
else:
self.title = title
if description is None:
self.description = self.DEFAULT_DESCRIPTION
else:
self.description = description
if tester is None:
self.tester = self.DEFAULT_TESTER
else:
self.tester = testerself.startTime = datetime.datetime.now()
def run(self, test):
"Run the given test case or test suite."
result = _TestResult(self.verbosity)
test(result)
self.stopTime = datetime.datetime.now()
self.generateReport(test, result)
#print(sys.stderr, '\nTime Elapsed: %s' % (self.stopTime-self.startTime))
print('\nTime Elapsed: %s' % (self.stopTime - self.startTime), file=sys.stderr)
return resultdef sortResult(self, result_list):
# unittest does not seems to run in any particular order.
# Here at least we want to group them together by class.
rmap = {}
classes = []
for n,t,o,e in result_list:
cls = t.__class__
if not cls in rmap:
rmap[cls] = []
classes.append(cls)
rmap[cls].append((n,t,o,e))
r = [(cls, rmap[cls]) for cls in classes]
return r#替换测试结果status为通过率 --Findyou
def getReportAttributes(self, result):
"""
Return report attributes as a list of (name, value).Override this to add custom attributes.
"""
startTime = str(self.startTime)[:19]
duration = str(self.stopTime - self.startTime)[:10]
status = []
status.append('【总共:%s】' % (result.success_count + result.failure_count + result.error_count))
if result.success_count:
status.append('【通过:%s】' % result.success_count)
if result.failure_count:
status.append('【失败:%s】' % result.failure_count)
if result.error_count:
status.append('【错误:%s】' % result.error_count)
if status:
status = ' '.join(status)
try:
self.passrate = str("%.2f%%" % (float(result.success_count) / float(result.success_count + result.failure_count + result.error_count) * 100))
except ZeroDivisionError:
self.passrate = 0
else:
status = 'none'
print(status)
return [
(u'测试人员', self.tester),
(u'开始时间',startTime),
(u'合计耗时',duration),
('测试结果',status + "【通过率= "+self.passrate+'】'),
]def generateReport(self, test, result):
report_attrs = self.getReportAttributes(result)
generator = 'HTMLTestRunner %s' % __version__
stylesheet = self._generate_stylesheet()
heading = self._generate_heading(report_attrs)
report = self._generate_report(result)
ending = self._generate_ending()
chart = self._generate_chart(result)
output = self.HTML_TMPL % dict(
title = saxutils.escape(self.title),
generator = generator,
stylesheet = stylesheet,
heading = heading,
report = report,
ending = ending,
chart_script=chart
)
self.stream.write(output.encode('utf8'))def _generate_stylesheet(self):
return self.STYLESHEET_TMPL#增加Tester显示 -Findyou
def _generate_heading(self, report_attrs):
a_lines = []
for name, value in report_attrs:
line = self.HEADING_ATTRIBUTE_TMPL % dict(
name = saxutils.escape(name),
value = saxutils.escape(value),
)
a_lines.append(line)
heading = self.HEADING_TMPL % dict(
title = saxutils.escape(self.title),
parameters = ''.join(a_lines),
description = saxutils.escape(self.description),
tester= saxutils.escape(self.tester),
)
return heading#生成报告 --Findyou添加注释
def _generate_report(self, result):
rows = []
sortedResult = self.sortResult(result.result)
for cid, (cls, cls_results) in enumerate(sortedResult):
# subtotal for a class
np = nf = ne = 0
for n,t,o,e in cls_results:
if n == 0: np += 1
elif n == 1: nf += 1
else: ne += 1# format class description
if cls.__module__ == "__main__":
name = cls.__name__
else:
name = "%s.%s" % (cls.__module__, cls.__name__)
doc = cls.__doc__ and cls.__doc__.split("\n")[0] or ""
desc = doc and '%s: %s' % (name, doc) or namerow = self.REPORT_CLASS_TMPL % dict(
style = ne > 0 and 'errorClass' or nf > 0 and 'failClass' or 'passClass',
desc = desc,
count = np+nf+ne,
Pass = np,
fail = nf,
error = ne,
cid = 'c%s' % (cid+1),
)
rows.append(row)for tid, (n,t,o,e) in enumerate(cls_results):
self._generate_report_test(rows, cid, tid, n, t, o, e)report = self.REPORT_TMPL % dict(
test_list = ''.join(rows),
count = str(result.success_count+result.failure_count+result.error_count),
Pass = str(result.success_count),
fail = str(result.failure_count),
error = str(result.error_count),
passrate =self.passrate,
)
return reportdef _generate_chart(self, result):
chart = self.ECHARTS_SCRIPT % dict(
Pass=str(result.success_count),
fail=str(result.failure_count),
error=str(result.error_count),
)
return chartdef _generate_report_test(self, rows, cid, tid, n, t, o, e):
# e.g. 'pt1.1', 'ft1.1', etc
has_output = bool(o or e)
# ID修改点为下划线,支持Bootstrap折叠展开特效 - Findyou
tid = (n == 0 and 'p' or 'f') + 't%s_%s' % (cid+1,tid+1)
name = t.id().split('.')[-1]
doc = t.shortDescription() or ""
desc = doc and ('%s: %s' % (name, doc)) or name
tmpl = has_output and self.REPORT_TEST_WITH_OUTPUT_TMPL or self.REPORT_TEST_NO_OUTPUT_TMPL# utf-8 支持中文 - Findyou
# o and e should be byte string because they are collected from stdout and stderr?
if isinstance(o, str):
# TODO: some problem with 'string_escape': it escape \n and mess up formating
# uo = unicode(o.encode('string_escape'))
# uo = o.decode('latin-1')
uo = o
else:
uo = o
if isinstance(e, str):
# TODO: some problem with 'string_escape': it escape \n and mess up formating
# ue = unicode(e.encode('string_escape'))
# ue = e.decode('latin-1')
ue = e
else:
ue = escript = self.REPORT_TEST_OUTPUT_TMPL % dict(
# id = tid,
id = '',
output = saxutils.escape(uo+ue),
)row = tmpl % dict(
tid = tid,
Class = (n == 0 and 'hiddenRow' or 'none'),
style = n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'passCase'),
desc = desc,
script = script,
status = self.STATUS[n],
)
rows.append(row)
if not has_output:
returndef _generate_ending(self):
return self.ENDING_TMPL##############################################################################
# Facilities for running tests from the command line
############################################################################### Note: Reuse unittest.TestProgram to launch test. In the future we may
# build our own launcher to support more specific command line
# parameters like test title, CSS, etc.
class TestProgram(unittest.TestProgram):
"""
A variation of the unittest.TestProgram. Please refer to the base
class for command line parameters."""
def runTests(self):
# Pick HTMLTestRunner as the default test runner.
# base class's testRunner parameter is not useful because it means
# we have to instantiate HTMLTestRunner before we know self.verbosity.
if self.testRunner is None:
self.testRunner = HTMLTestRunner(verbosity=self.verbosity)
unittest.TestProgram.runTests(self)main = TestProgram
##############################################################################
# Executing this module from the command line
##############################################################################if __name__ == "__main__":
main(module=None)Original: https://www.cnblogs.com/qmfsun/p/11558063.html
Author: Agoly
Title: Unitest自动化测试基于HTMLTestRunner报告案例
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/549142/
转载文章受原作者版权保护。转载请注明原作者出处!