import time
import os
from jinja2 import Environment, FileSystemLoader
class TestReport():
def __init__(self,
filename="report.html",
report_dir="../reports",
title='测试报告',
tester='测试员',
desc="XX项目测试生成的报告",
templates=1
):
"""
:param suites: test suite
:param filename: Report file name
:param report_dir:The path to the report file
:param title:Test suite title
:param templates: You can specify the style template for the report by parameter value 1 or 2. Currently, there are only two templates
:param tester:Tester
"""
# if not isinstance(suite, unittest.TestSuite):
# raise TypeError("Parameter suite is not a test suite")
# if not isinstance(filename, str):
# raise TypeError("filename is not str")
# if not filename.endswith(".html"):
# filename = filename + ".html"
self.filename = filename
self.title = title
self.tester = tester
self.desc = desc
self.templates = templates
self.report_dir = report_dir
self.result = []
self.starttime = time.time()
def get_reports(self, test_result):
print("所有用例执行完毕,正在生成测试报告中......")
# test_result = {
# "success": 0,
# "all": 0,
# "fail": 0,
# "skip": 0,
# "error": 0,
# "results": [],
# "testClass": [],
# }
# for res in self.result:
# for item in test_result:
# test_result[item] += res.fields[item]
test_result['runtime'] = '{:.2f} S'.format(time.time() - self.starttime)
test_result["begin_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.starttime))
test_result["title"] = self.title
test_result["tester"] = self.tester
test_result['desc'] = self.desc
if test_result['all'] != 0:
test_result['pass_rate'] = '{:.2f}'.format(test_result['success'] / test_result['all'] * 100)
else:
test_result['pass_rate'] = 0
# 判断是否要生产测试报告
if os.path.isdir(self.report_dir):
pass
else:
os.mkdir(self.report_dir)
# 获取历史执行数据
# test_result['history'] = self.__handle_history_data(test_result)
template_path = os.path.join(os.path.dirname(__file__), './templates')
env = Environment(loader=FileSystemLoader(template_path))
if self.templates == 2:
template = env.get_template('templates2.html')
elif self.templates == 3:
template = env.get_template('templates3.html')
else:
template = env.get_template('templates.html')
file_path = os.path.join(self.report_dir, self.filename)
res = template.render(test_result)
with open(file_path, 'wb') as f:
f.write(res.encode('utf8'))
print("测试报告已经生成,报告路径为:{}".format(file_path))
self.email_conent = {"file": os.path.abspath(file_path),
"content": env.get_template('templates03.html').render(test_result)
}
self.test_result = test_result
return test_result
if __name__=='__main__':
test_result = {
"success": 75,
"fail": 25,
"all": 100,
"skip": 0,
"error": 0,
}
runner = TestReport()
runner.get_reports(test_result)
运行结果:
D:Python3.8.6python.exe D:/PythonWorkSpace/chenbang/test_10.py 所有用例执行完毕,正在生成测试报告中...... 测试报告已经生成,报告路径为:../reportsreport.html Process finished with exit code 0
运行截图:
运行代码报错jinja2.exceptions.TemplateNotFound: templates.html时,下载链接模板,放在运行代码同目录下
我设置成0积分下载,点击立即下载即可。
https://download.csdn.net/download/qq_42069296/85948174
二.模板2import json
import os
import time
from jinja2 import Environment, FileSystemLoader
class MyTest:
def __init__(self,filename="report.html",
report_dir="../reports",
title='测试报告',
tester='测试员',
desc="XX项目测试生成的报告",
templates=1):
# self.suite = None
self.filename = filename
self.title = title
self.tester = tester
self.desc = desc
self.templates = 2
self.report_dir = report_dir
# self.result = [{'aa':{}}]
self.starttime = time.time()
def get_reports(self,test_result):
print("所有用例执行完毕,正在生成测试报告中......")
# test_result = {
# "success": 0,
# "all": 0,
# "fail": 0,
# "skip": 0,
# "error": 0,
# "results": [],
# "testClass": [],
# }
# for res in self.result:
# for item in test_result:
# test_result[item] += res.fields[item]
test_result['runtime'] = '{:.2f} S'.format(time.time() - self.starttime)
test_result["begin_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.starttime))
test_result["title"] = self.title
test_result["tester"] = self.tester
test_result['desc'] = self.desc
if test_result['all'] != 0:
test_result['pass_rate'] = '{:.2f}'.format(test_result['success'] / test_result['all'] * 100)
else:
test_result['pass_rate'] = 0
# 判断是否要生成测试报告目录
if os.path.isdir(self.report_dir):
pass
else:
os.mkdir(self.report_dir)
# 获取历史执行数据
test_result['history'] = self.__handle_history_data(test_result)
template_path = os.path.join(os.path.dirname(__file__), './templates')
print(template_path)
# template_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'templates')
env = Environment(loader=FileSystemLoader(template_path))
if self.templates == 2:
template = env.get_template('templates2.html')
elif self.templates == 3:
template = env.get_template('templates3.html')
else:
template = env.get_template('templates.html')
# file_path = os.path.join(self.report_dir, self.filename)
file_path = os.path.join(os.path.abspath(self.report_dir), self.filename)
res = template.render(test_result)
with open(file_path, 'wb') as f:
f.write(res.encode('utf8'))
print("测试报告已经生成,报告路径为:{}".format(file_path))
# self.email_conent = {"file": os.path.abspath(file_path),
# "content": env.get_template('templates03.html').render(test_result)
# }
self.test_result = test_result
return test_result
def __handle_history_data(self, test_result):
"""
处理历史数据
:return:
"""
try:
with open(os.path.join(self.report_dir, 'history.json'), 'r', encoding='utf-8') as f:
history = json.load(f)
except FileNotFoundError as e:
history = []
history.append({'success': test_result['success'],
'all': test_result['all'],
'fail': test_result['fail'],
'skip': test_result['skip'],
'error': test_result['error'],
'runtime': test_result['runtime'],
'begin_time': test_result['begin_time'],
'pass_rate': test_result['pass_rate'],
})
with open(os.path.join(self.report_dir, 'history.json'), 'w', encoding='utf-8') as f:
json.dump(history, f, ensure_ascii=True)
return history
if __name__ == '__main__':
test_result = {
"success": 40,
"all": 50,
"fail": 5,
"skip":1,
"error": 4,
"results": [],
"testClass": [],
}
tt = MyTest()
tt.get_reports(test_result)
运行结果:
D:Python3.8.6python.exe D:/PythonWorkSpace/chenbang/test1.py 所有用例执行完毕,正在生成测试报告中...... D:/PythonWorkSpace/chenbang./templates 测试报告已经生成,报告路径为:D:PythonWorkSpacereportsreport.html Process finished with exit code 0
运行截图:
该模板的优势是统计了历史数据
三.源码:https://unittestreport.readthedocs.io/en/latest/doc2_report/上述两段代码都是对以下源码进行的二次封装
class TestRunner():
def __init__(self, suite: unittest.TestSuite,
filename="report.html",
report_dir="./reports",
title='测试报告',
tester='测试员',
desc="XX项目测试生成的报告",
templates=1
):
"""
:param suites: test suite
:param filename: Report file name
:param report_dir:The path to the report file
:param title:Test suite title
:param templates: You can specify the style template for the report by parameter value 1 or 2. Currently, there are only two templates
:param tester:Tester
"""
if not isinstance(suite, unittest.TestSuite):
raise TypeError("Parameter suite is not a test suite")
if not isinstance(filename, str):
raise TypeError("filename is not str")
if not filename.endswith(".html"):
filename = filename + ".html"
self.suite = suite
self.filename = filename
self.title = title
self.tester = tester
self.desc = desc
self.templates = templates
self.report_dir = report_dir
self.result = []
self.starttime = time.time()
def __get_reports(self):
print("所有用例执行完毕,正在生成测试报告中......")
test_result = {
"success": 0,
"all": 0,
"fail": 0,
"skip": 0,
"error": 0,
"results": [],
"testClass": [],
}
for res in self.result:
for item in test_result:
test_result[item] += res.fields[item]
test_result['runtime'] = '{:.2f} S'.format(time.time() - self.starttime)
test_result["begin_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(self.starttime))
test_result["title"] = self.title
test_result["tester"] = self.tester
test_result['desc'] = self.desc
if test_result['all'] != 0:
test_result['pass_rate'] = '{:.2f}'.format(test_result['success'] / test_result['all'] * 100)
else:
test_result['pass_rate'] = 0
# 判断是否要生产测试报告
if os.path.isdir(self.report_dir):
pass
else:
os.mkdir(self.report_dir)
# 获取历史执行数据
test_result['history'] = self.__handle_history_data(test_result)
template_path = os.path.join(os.path.dirname(__file__), '../templates')
env = Environment(loader=FileSystemLoader(template_path))
if self.templates == 2:
template = env.get_template('templates2.html')
elif self.templates == 3:
template = env.get_template('templates3.html')
else:
template = env.get_template('templates.html')
file_path = os.path.join(self.report_dir, self.filename)
res = template.render(test_result)
with open(file_path, 'wb') as f:
f.write(res.encode('utf8'))
print("测试报告已经生成,报告路径为:{}".format(file_path))
self.email_conent = {"file": os.path.abspath(file_path),
"content": env.get_template('templates03.html').render(test_result)
}
self.test_result = test_result
return test_result
def __handle_history_data(self, test_result):
"""
处理历史数据
:return:
"""
try:
with open(os.path.join(self.report_dir, 'history.json'), 'r', encoding='utf-8') as f:
history = json.load(f)
except FileNotFoundError as e:
history = []
history.append({'success': test_result['success'],
'all': test_result['all'],
'fail': test_result['fail'],
'skip': test_result['skip'],
'error': test_result['error'],
'runtime': test_result['runtime'],
'begin_time': test_result['begin_time'],
'pass_rate': test_result['pass_rate'],
})
with open(os.path.join(self.report_dir, 'history.json'), 'w', encoding='utf-8') as f:
json.dump(history, f, ensure_ascii=True)
return history



