使用python + unittest生成测试报告,目前网上最普遍的是两个开源方法:
- HTMLTestRunner
- HtmlTestRunner
两者对比
其中第2个是基于第1个实现的;第1个已经不维护了,如果应用到py3,需要自己做一些修改,此外,样式并不好看( ╯□╰ )。
第2个相对第1个,支持py3,而且样式也漂亮了一些,安装也方便了。
在使用HtmlTestRunner时遇到下面的问题:
1. 有两个测试用例文件:test_login.py
和test_create.py
,生成了两份html报告。
2. 没有截图啊
然后自己捣鼓捣鼓做了一些修改,因为WEB UI自动化目前想应用到的是浏览器兼容性测试,因此以为目的,修改如下:
HtmlTestrunner/runner.py
修改点:添加参数(other_info)传入浏览器等信息,生成图片的时候,以浏览器名称为目录名保存截图,以免多线程跑多个浏览器时截图被覆盖
修改后代码:
class HTMLTestRunner(TextTestRunner):
"""" A test runner class that output the results. """
def __init__(self, output, verbosity=2, stream=sys.stderr,
descriptions=True, failfast=False, buffer=False,
report_title=None, template=None, resultclass=None, other_info=[]):
self.verbosity = verbosity
self.output = output
self.encoding = UTF8
self.other_info = other_info
......
def _make_result(self):
""" Create a TestResult object which will be used to store
information about the executed tests. """
return self.resultclass(self.stream, self.descriptions, self.verbosity,
self.elapsed_times, self.other_info)
差异对比截图:
左:修改后的runner.py 右:HtmlTestRunner/runner.py
HtmlTestrunner/result.py
修改点:改了2个方法(_HtmlTestResult._report_tests, _HtmlTestResult.generate_reports),加了1个方法(_HtmlTestResult.get_images)。解决的问题:
1. 测试用例存在于多个*.py文件中时,都展示在同一个报告中;
2. 获取用例的截图,以展示在报告中
- _HtmlTestResult._report_tests方法修改
修改后代码:
def _report_tests(self, test_class_name, tests, testRunner):
""" Generate a html file for a given suite. """
test_cases_list = []
# Sort test by number if they have
tests = self.sort_test_list(tests)
for test in tests:
self._report_testcase(test, test_cases_list)
index = tests.index(test)
test_description = test.test_description
images_list = self.get_images(test_description.split('(')[0])
test_cases_list[index].append(images_list)
return test_cases_list
差异对比截图
左:修改后的 右:原来的
- _HtmlTestResult.generate_reports方法修改
修改后代码:
def generate_reports(self, testRunner):
""" Generate report for all given runned test object. """
report_name = testRunner.report_title
all_results = self._get_info_by_testcase()
start_time = testRunner.start_time
elapsed_time = testRunner.time_taken
test_cases_list = []
testcase_name = []
total_test = 0
all_tests_list = []
for testcase_class_name, all_tests in all_results.items():
if testRunner.outsuffix:
testcase_class_name = "Test_{}_{}.html".format(testcase_class_name,
testRunner.outsuffix)
testcase_name_tmp = testcase_class_name.split("_")[1]
all_tests_list.extend(all_tests)
tests = self._report_tests(testcase_name_tmp, all_tests,
testRunner)
test_cases_list.append(tests)
testcase_name.append(testcase_name_tmp)
report_headers, total_test = self.get_report_attributes(all_tests_list, start_time, elapsed_time)
total_test = len(all_tests_list)
tests_html_file = render_html(testRunner.template, title=report_name,
headers=report_headers,
testcase_name=testcase_name,
tests_results=test_cases_list,
total_test=total_test)
report_file_name = "{}_{}.html".format(report_name, testRunner.outsuffix)
self.generate_file(testRunner.output, report_file_name,
tests_html_file)
差异对比截图:
左:修改后的 右:原来的
- 增加了一个_HtmlTestResult.get_images方法
def get_images(self, dir_name):
'''
get images of test case
:param dir_name: test case name
'''
dir_name = dir_name.strip()
current_dir = '.'
images_dir_root = os.path.join(current_dir, 'reports', 'images',self.other_info[1], self.other_info[0])
images_list = []
search_dir_path = os.path.join(images_dir_root, dir_name)
if not os.path.exists(search_dir_path):
os.makedirs(search_dir_path)
for image in os.listdir(search_dir_path):
image_full_path = os.path.join(search_dir_path, image)
if os.path.isfile(image_full_path):
image_path = os.path.join('.', 'images', self.other_info[1], self.other_info[0], dir_name, image)
images_list.append(image_path)
return images_list
另外,此方法中用到了self.other_info
,这个是在_HtmlTestResult.__init__
方法中定义的:
class _HtmlTestResult(_TextTestResult):
""" A test result class that express test results in Html. """
def __init__(self, stream, descriptions, verbosity, elapsed_times, other_info):
_TextTestResult.__init__(self, stream, descriptions, verbosity)
'''
:param other_info = [browser_name, image_dir], image_dir: base, current, compatibility
'''
self.buffer = True
self._stdout_data = None
self._stderr_data = None
self.successes = []
self.callback = None
self.elapsed_times = elapsed_times
self.infoclass = _TestInfo
self.other_info = other_info
HtmlTestrunner/template/result_template.html
修改点:支持将截图展示在报告中;支持多个testclass时的展示
修改后的html代码示例:
<!DOCTYPE html>
<html>
......
<body>
<div class="container">
......
<div class="row">
<div class="col-xs-12 col-sm-10 col-md-10">
<table class='table table-hover table-responsive'>
{% for TestCase in tests_results %}
<thead>
<tr>
<th>{{testcase_name[loop.index0]}}</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for eachTestCase, status, errorType, errorMessage, images_list in TestCase %}
......
<tr style="display:none;">
<td class="col-xs-9">
<p>{{errorType}}</p>
<p>{{errorMessage}}</p>
{% for eachImg in images_list %}
<p>
<img src={{eachImg}} width="1280" height="620" />
</p>
{% endfor %}
</td>
</tr>
{% endfor %}
{% endfor %}
......
差异对比截图
左:修改后的;右:HtmlTestRunner/template/report_template.html
最后放个结果图
下载地址:https://download.csdn.net/download/u010895119/10865124
参考:
- jinjia2(HtmlTestRunner生成html报告是用了jinjia2,很直观且方便,学习成本很低)
- HtmlTestRunner