起因:
由于想要自己练习一下在网上学到的unittest+多线程的接口自动化测试项目,但是课程上并没有讲如何输出测试报告,
这里需要讲一下我运行的项目背景是1个用例文件,一共有10个用例,需求是一次启动10个线程,一次性执行完毕这10个用例,话不多说,上代码
run.pycode
def load_testcase(testfile):
modules = unittest.TestLoader().discover('./case', testfile)
return modules
@threads(10)
def run_testcase(testcase, counts):
result = BeautifulReport(testcase)
result.report('测试报告', filename='./report/report.html')
if __name__ == '__main__':
modules = load_testcase('test*.py')
for i in modules:
run_testcase(i)
code
在网上搜索了一下找到了👇这篇文章,并按照大佬的思路改了一下
改造BeautifulReport适用于unittest单、多线程执行,输出测试报告
更改后,虽然输出了报告,但是仍然存在问题:
1、输出的报告得不到数量,且下方详细中没有展示任何用例
大佬的思路是,
1、添加全局变量用来接收每次执行的测试类所有的用例数量
2、在每次用例结束之前,添加用例数量到全局变量中,这样,最后就可以收集到所有数量
这个思路没有问题,但是阅读stopTestRun方法后,我发现收集的变量还不够,于是我
补充了全局变量,并且在方法中收集数量和内容
ReportTestResultcode
testcaseAll =0
testFailAll =0
testPassAll =0
result_list_all = []
code
stopTestRuncode
#所有成功的数量
ReportTestResult.testPassAll += self.success_counter
self.fields['testPass'] += ReportTestResult.testPassAll
#所有执行用例的内容
ReportTestResult.result_list_all.extend(self.result_list)
for item in ReportTestResult.result_list_all:
item = json.loads(str(MakeResultJson(item)))
self.fields.get('testResult').append(item)
#所有执行用例的数量
ReportTestResult.testcaseAll = len(ReportTestResult.result_list_all)
self.fields['testAll'] = ReportTestResult.testcaseAll
#所有失败的数量
ReportTestResult.testFailAll += self.failure_count
self.fields['testFail'] = ReportTestResult.testFailAll
code
再次运行代码,发现这回数量和下方的内容都有了,但是仍然存在问题:
2、数量和内容都是1,且每执行一次,显示的那一个内容都不统一
一开始我以为仍然是上一个问题没有解决,于是我追溯到这些数量输出到文件的地方
report方法下的output_report。
在output_report方法调用的上方打印数量发现:
- 10个进程中,总有1个是集齐了所有测试用例结果的线程,全局变量是正确的
- 由于每个线程都会最后输出report.html文件,之前一开始理想情况是集齐了所有测试用例结果的线程会覆盖成最后的文件,但现实却是最后一个io输出文件的并不一定是这个集齐了所有测试结果的线程。
之前的思路是每个线程都会覆盖,覆盖到最后一个是所有测试用例结果的线程,目前看来是不work的,所以改进后的思路是,只要测试用例没有全部收集完,就不输出report.html文件
为了让程序知晓测试用例是否收集完,需要给出用例总数,所以我更改了入参,并根据用例总数判断是否进入output_report。
run.pycode
@threads(10)
def run_testcase(testcase, counts):
result = BeautifulReport(testcase)
result.report(counts, '测试报告', filename='./report/report.html')
code
reportcode
if counts != self.fields['testAll']:
return
self.output_report(theme)
text = '\n测试已全部完成, 可打开 {} 查看报告'.format(os.path.join(self.report_dir, self.filename))
print(text)
code
得到用例数量也比较好拿到,只要对unittest熟悉。
code
modules = load_testcase('test*.py')
test_lst = [test for suites in modules for tests in suites for test in tests]
cases_num = len(test_lst)
code