介面自動化測試報告html模板
阿新 • • 發佈:2018-12-22
研究了下好幾個介面自動化報告的模板,自己改造了個帶餅圖的介面自動化模板,先貼報告吧~
在貼程式碼如下:
# *-*coding:utf-8*-*
"""@version: Python3.4.4
@author: Hszhang
@time: 2017/6/14 16:34
- 使用bottle來動態生成html
- https://www.reddit.com/r/learnpython/comments/2sfeg0/using_template_engine_with_python_for_generating/
"""from bottle import template
import webbrowser
import json
import sys
html_template = u"""
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head>
<title>介面測試報告</title>
<meta name="generator" content="HTMLTestRunner 0.8.2.2"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link href="http://libs.baidu.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="http://libs.baidu.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<!-- 引入 echarts.js -->
<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts-all-3.js"></script>
<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts-stat/ecStat.min.js"></script>
<script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/extension/dataTool.min.js"></script>
<style type="text/css" media="screen">
body {
margin: 0;
font-family: "Arial", "Microsoft YaHei", "黑體", "宋體", sans-serif;
font-size: 18px;
line-height: 1.5;
line-height: 1.5;
color: #333333;
}
.table {
margin-bottom: 1px;
width: 100%;
}
.hiddenRow {
display: none;
}
.container-fluid {
padding-right: 120px;
padding-left: 120px;
}
.nav-tabs li {
width: 186px;
text-align: center;
}
</style>
</head>
<body >
<script language="javascript" type="text/javascript">
function showClassDetail(detail_id, hiddenRow_id, class_type) {
console.log(document.getElementById(hiddenRow_id).className)
if ('詳細' == document.getElementById(detail_id).innerText) {
if ('all' == class_type) {
document.getElementById(hiddenRow_id).className = 'all';
}
else if ('success' == class_type) {
document.getElementById(hiddenRow_id).className = 'success';
}
else if ('error' == class_type) {
document.getElementById(hiddenRow_id).className = 'error';
}
else{
document.getElementById(hiddenRow_id).className = 'untreaded';
}
document.getElementById(detail_id).innerText = "收起"
}
else {
document.getElementById(detail_id).innerText = "詳細"
document.getElementById(hiddenRow_id).className = 'hiddenRow';
}
}
</script>
<div class="container-fluid">
<div class="page-header">
<h1 class="text-primary" style="font-size:45px;line-height:75px">介面自動化測試報告</h1>
</div>
<div class="col-md-12">
<div class="col-md-4" style="Background-Color:#F5F5F5; height:300px">
<h3 style="line-height:25px">測試基本資訊</h3>
<table class="table table-hover table-bordered" style="width:100% height:11px">
<tbody>
<tr class="info">
<td class="text-center">開始時間</td>
<td class="text-center">{{start_time}}</td>
</tr>
<tr class="info">
<td class="text-center">結束時間</td>
<td class="text-center">{{end_time}}</td>
</tr>
<tr class="info">
<td class="text-center">測試用時</td>
<td class="text-center">{{used_time}}</td>
</tr>
<tr class="info">
<td class="text-center">總用例數</td>
<td class="text-center">{{sum_all_cases}}</td>
</tr>
<tr class="info">
<td class="text-center">執行用例數</td>
<td class="text-center">{{sum_executed_cases}}</td>
</tr>
<tr class="info">
<td class="text-center">跳過用例數</td>
<td class="text-center">{{sum_untreaded_cases}}</td>
</tr>
</tbody>
</table>
</div>
<div class="col-md-8">
<!-- 為ECharts準備一個具備大小(寬高)的Dom -->
<div id="main" style="height:300px;"></div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var option = {
backgroundColor: '#F5F5F5', //背景色
title: {
text: '測試統計資料',
x: 'center'
},
legend: {
orient: 'vertical',
x: 'left',
data: ['成功', '失敗', '未檢驗']
},
color: ['#3c763d', '#a94442', '#0099CC'],
calculable: true,
series: [{
name: '測試結果',
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
startAngle: 135,
data: [{
value: {{right_sum}},
name: '成功',
itemStyle: {
normal: {
label: {
formatter: '{b} : {c} ({d}%)',
textStyle: {
align: 'left',
fontSize: 15,
}
},
labelLine: {
length: 40,
}
}
}
}, {
value: {{error_sum}},
name: '失敗',
itemStyle: {
normal: {
label: {
formatter: '{b} : {c} ({d}%)',
textStyle: {
align: 'right',
fontSize: 15,
}
},
labelLine: {
length: 40,
}
}
}
}, {
value: {{untreated_sum}},
name: '未檢驗',
itemStyle: {
normal: {
label: {
formatter: '{b} : {c} ({d}%)',
textStyle: {
align: 'right',
fontSize: 15,
}
},
labelLine: {
length: 40,
}
}
}
}],
}]
};
// 為echarts物件載入資料
myChart.setOption(option);
</script>
</div>
</div>
"""
REPORT_TMPL_Lable = '''
<div><span> </span></div>
<div class="col-md-12">
<div class="tabbable" id="tabs-957640">
<ul class="nav nav-tabs">
<li class="active">
<a href="#panel-0" data-toggle="tab" style="Background-Color: #428bca; color: #fff;">全 部 ({})</a>
</li>
<li>
<a href="#panel-1" data-toggle="tab" style="Background-Color: #d9534f; color: #fff;">成 功 ({})</a>
</li>
<li>
<a href="#panel-2" data-toggle="tab" style="Background-Color: #5cb85c; color: #fff;">失 敗 ({})</a>
</li>
<li>
<a href="#panel-3" data-toggle="tab" style="Background-Color: #5bc0de; color: #fff;">未驗證 ({})</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="tab-pane active" id="panel-0">
<table class="table table-hover table-bordered">
{}
</table>
</div>
<div class="tab-pane" id="panel-1">
<table class="table table-hover table-bordered">
{}
</table>
</div>
<div class="tab-pane" id="panel-2">
<table class="table table-hover table-bordered">
{}
</table>
</div>
<div class="tab-pane" id="panel-3">
<table class="table table-hover table-bordered">
{}
</table>
</div>
</div>
</div>
</div>
</body>
</html>
'''
REPORT_TMPL_Title = '''
<table class="table table-hover table-bordered" style="Background-Color:#dff0d8">
<thead>
<colgroup>
{}
</colgroup>
<tr>
{}
</tr>
</thead>
<tbody></tbody>
</table>
'''
REPORT_Title_Width = ''' <col width='{}%'/>
'''
REPORT_Title_Lable = ''' <td class="text-center" style="Background-Color:#dff0d8">{}</td>
'''
REPORT_Table_Data = ''' <td class="text-center">{}</td>
'''
REPORT_Table_Detail = ''' <td class="text-center"><a href="javascript:showClassDetail('{}','{}', '{}')" class="detail" id = "{}">詳細</a></td>
'''
EXPORT_Detali_text = ''' <tr class='hiddenRow' id="{}" >
<td colspan='{}'>
<div>
<pre class="text-left">
{}
</pre>
</div>
</td>
</tr>
'''
class HTML_REPORT:
def __init__(self, html_title, pie_theme, test_info, report_table_title, report_cases):
'''
@parameter html_title:HTML標題,字串型別,如html_title = u'介面測試報告'
@parameter pie_theme:,餅圖名稱,字串型別,pie_theme = u'介面資料統計'
@parameter test_info:,餅圖資料統計,列表型別,長度 = 6,如test_info = ['2016-12-02 15:59:17', '2016-12-02 16:10:22', '11 分 4 秒', len(report_cases['all_cases']), len(report_cases['right_cases']) + len(report_cases['error_cases']), len(report_cases['untreaded_cases'])]
@parameter report_table_title:介面表格標題,列表型別,可以自定義,report_cases = ['專案名稱', '用例編號', '用例名稱', '介面地址', '介面方法', '測試結果', '詳細資訊']
@parameter report_cases:介面測試結果記錄,字典格式且key不能變,report_cases = {'all_cases':[['WEB理財', '1', '登入', 'login', 'post', 'pass', '詳細資訊', ''],['WEB理財', '2', '產品列表', 'list', 'post', 'error', '詳細資訊', '']],
'right_cases':[['WEB理財', '1', '登入', 'login', 'post', 'pass', '詳細資訊', '']],
'error_cases':[['WEB理財', '2', '產品列表', 'list', 'post', 'error', '詳細資訊', '']],
'untreaded_cases':[['WEB理財', '3', '測試', 'login', 'post', '/', '詳細資訊', '']]
}
'''
if isinstance(html_title, str) and len(html_title) > 0:
self.html_title = html_title
else:
self.html_title = u'介面測試報告'
if isinstance(pie_theme, str) and len(pie_theme) > 0:
self.pie_theme = pie_theme
else:
self.theme = u'介面資料統計'
if isinstance(report_table_title, list) and len(report_table_title) > 0:
self.report_table_title = report_table_title
else:
print('nothing of report_table_title.')
sys.exit(0)
if isinstance(test_info, list) and 6 == len(test_info):
self.test_info = test_info
else:
print('nothing of test_info.')
sys.exit(0)
if isinstance(report_cases, dict) and len(report_cases) > 0:
self.report_cases = report_cases
self.pie_sum_number = {'right_sum': len(report_cases['right_cases']) ,'error_sum': len(report_cases['error_cases']), 'untreated_sum': len(report_cases['untreaded_cases'])}
else:
print('nothing of report_cases or length is not 6.')
sys.exit(0)
def packagedCases(self, export_lable_title, data_key, class_name, pannel_num):
cases_num = 1
cases_packaged = ''
cases_packaged = ''.join([cases_packaged,\
' <tr class="{}">\n'.format(class_name),\
export_lable_title,
' </tr>\n'])
for data_case in self.report_cases[data_key]:
detail_id = ''.join([pannel_num, '-detail-', str(cases_num)])
hidden_id = ''.join([pannel_num, '-hidden-', str(cases_num)])
cases_num += 1
cases_packaged = ''.join([cases_packaged, ' <tr class="{}">\n'.format(class_name)])
for data in data_case[:-1]:
if '詳細' == data:
cases_packaged = ''.join([cases_packaged, REPORT_Table_Detail.format(detail_id, hidden_id, 'success', detail_id)])
else:
cases_packaged = ''.join([cases_packaged, REPORT_Table_Data.format(data)])
cases_packaged = ''.join([cases_packaged, ' </tr>\n'])
cases_packaged = ''.join([cases_packaged, EXPORT_Detali_text.format(hidden_id, len(data_case) - 1, data_case[-1])])
return cases_packaged
def genHtmlReport(self, html_template):
export_lable_title = ''
for lable_tile in self.report_table_title:
export_lable_title = ''.join([export_lable_title, REPORT_Title_Lable.format(lable_tile)])
str_right_datas = ''
str_untreated_cases = ''
str_error_cases = ''
str_all_cases = ''
for data_key in self.report_cases.keys():
if 'right_cases' == data_key:
str_right_datas = self.packagedCases(export_lable_title, data_key, 'success', 'panel1')
elif 'untreaded_cases' == data_key:
str_untreated_cases = self.packagedCases(export_lable_title, data_key, 'untreaded', 'panel3')
elif 'error_cases' == data_key:
str_error_cases = self.packagedCases(export_lable_title, data_key, 'error', 'panel2')
else:
str_all_cases = self.packagedCases(export_lable_title, data_key, 'all', 'panel0')
'''
right_cases_num = 1
str_right_datas = ''.join([str_right_datas,\
' <tr class="success">\n',\
export_lable_title,
' </tr>\n'])
for data_case in self.report_cases[data_key]:
right_detail_id = ''.join(['panel1-detail-', str(right_cases_num)])
right_hidden_id = ''.join(['panel1-hidden-', str(right_cases_num)])
right_cases_num += 1
str_right_datas = ''.join([str_right_datas, ' <tr class="success">\n'])
for data in data_case[:-1]:
if '詳細' == data:
str_right_datas = ''.join([str_right_datas, REPORT_Table_Detail.format(right_detail_id, right_hidden_id, 'success', right_detail_id)])
else:
str_right_datas = ''.join([str_right_datas, REPORT_Table_Data.format(data)])
str_right_datas = ''.join([str_right_datas, ' </tr>\n'])
str_right_datas = ''.join([str_right_datas, EXPORT_Detali_text.format(right_hidden_id, len(data_case) - 1, data_case[-1])])
elif 'untreaded_cases' == data_key:
str_untreated_cases = ''.join([str_untreated_cases,\
' <tr class="untreaded">\n',\
export_lable_title,
' </tr>\n'])
for data_case in self.report_cases[data_key][:-1]:
str_untreated_cases = ''.join([str_untreated_cases, ' <tr class="untreaded">\n'])
for data in data_case:
if '詳細' in data:
str_untreated_cases = ''.join([str_untreated_cases,REPORT_Table_Detail.format(data)])
else:
str_untreated_cases = ''.join([str_untreated_cases, REPORT_Table_Data.format(data)])
str_untreated_cases = ''.join([str_untreated_cases, ' </tr>\n'])
elif 'error_cases' == data_key:
str_error_cases = ''.join([str_error_cases,\
export_lable_title,
' <tr class="error">\n',\
' </tr>\n'])
for data_case in self.report_cases[data_key][:-1]:
str_error_cases = ''.join([str_error_cases, ' <tr class="error">\n'])
for data in data_case:
if '詳細' in data:
str_error_cases = ''.join([str_error_cases,REPORT_Table_Detail.format(data)])
else:
str_error_cases = ''.join([str_error_cases, REPORT_Table_Data.format(data)])
str_error_cases = ''.join([str_error_cases, ' </tr>\n'])
elif 'all_cases' == data_key:
str_all_cases = ''.join([str_all_cases,\
' <tr class="all">\n',\
export_lable_title,
' </tr>\n'])
for data_case in self.report_cases[data_key][:-1]:
str_all_cases = ''.join([str_all_cases, ' <tr class="all">\n'])
for data in data_case:
if '詳細' == data:
str_all_cases = ''.join([str_all_cases, REPORT_Table_Detail.format(data)])
else:
str_all_cases = ''.join([str_all_cases, REPORT_Table_Data.format(data)])
str_all_cases = ''.join([str_all_cases, ' </tr>\n'])
'''
export_lable_datas = REPORT_TMPL_Lable.format(len(report_cases['all_cases']),len(report_cases['right_cases']),len(report_cases['error_cases']),len(report_cases['untreaded_cases']),\
str(str_all_cases[0:-1]),\
str(str_right_datas[0:-1]),\
str(str_error_cases[0:-1]),\
str(str_untreated_cases[0:-1]))
html_template = ''.join([html_template, export_lable_datas])
html = template(html_template, report_title = self.html_title, theme = self.pie_theme,\
start_time = self.test_info[0], end_time = self.test_info[1], used_time = self.test_info[2], sum_all_cases = self.test_info[3], sum_executed_cases = self.test_info[4], sum_untreaded_cases = self.test_info[5],\
right_sum = self.pie_sum_number['right_sum'], error_sum = self.pie_sum_number['error_sum'], untreated_sum = self.pie_sum_number['untreated_sum'])
return html
if __name__ == '__main__':
report_title = u'介面測試報告'
theme = u'介面資料統計'
report_table_title = ['專案名稱', '用例編號', '用例名稱', '介面地址', '介面方法', '測試結果', '詳細資訊']
sim_card_service.get_flow_by_serial Test failure!
Because of : Data check failure,AssertionError!
Data Should : sim_card_service.get_flow_by_serial
Data Actually : sim_card_service.get_flow_by_serial , 6.4413928985596
Response Json tree:
{
"msg": {
"message": "failed",
"code": -1,
"data": "該號碼不存在"
},
"code": -1,
"trace": "sim_card_service.get_flow_by_serial , 6.4413928985596"
}
'''
report_cases = {'all_cases':[\
['理財', '1', '登入', 'lo144444444444444444444444444444444444444444444444444444444444444gin', 'post', 'Pass', '詳細', case_detail],\
['WEB理財', '2', '產品列表', 'list', 'post', 'Fail', '詳細', case_detail],\
['理財', '3', '測試', 'login', 'po6666666666666666666666666666666666666666666666666666st', '/', '詳細', case_detail]\
],
'right_cases':[['理財', '1', '登入', 'login', 'po22222222222222222222222222222st', 'Pass', '詳細', case_detail]],
'error_cases':[['理財', '2', '產品列表', 'list', 'pos5555555555555555555555t', 'Fail', '詳細', case_detail]],
'untreaded_cases':[['WEB理財', '3', '測試', 'login', 'po6666666666666666666666666666666666666666666666666666st', '/', '詳細', case_detail]]
}
test_info = ['2016-12-02 15:59:17', '2016-12-02 16:10:22', '11 分 4 秒', len(report_cases['all_cases']), len(report_cases['right_cases']) + len(report_cases['error_cases']), len(report_cases['untreaded_cases'])]
html_report_object = HTML_REPORT(report_title, theme, test_info, report_table_title, report_cases)
html = html_report_object.genHtmlReport(html_template)
with open("test_demo.html",'wb') as f:
f.write(html.encode('utf-8'))
#使用瀏覽器開啟html
webbrowser.open("test_demo.html")