使用新版的BSTestRunner执行,增加历史结果统计和重试功能
This commit is contained in:
@@ -93,12 +93,11 @@ Version in 0.7.1
|
||||
# TODO: simplify javascript using ,ore than 1 class in the class attribute?
|
||||
|
||||
import datetime
|
||||
from io import StringIO as StringIO
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
from xml.sax import saxutils
|
||||
|
||||
import os
|
||||
import sys, copy
|
||||
from io import StringIO as StringIO
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# The redirectors below are used to capture output during testing. Output
|
||||
@@ -185,12 +184,12 @@ class Template_mixin(object):
|
||||
"""
|
||||
|
||||
STATUS = {
|
||||
0: 'pass',
|
||||
1: 'fail',
|
||||
2: 'error',
|
||||
0: '通过',
|
||||
1: '失败',
|
||||
2: '错误',
|
||||
}
|
||||
|
||||
DEFAULT_TITLE = 'Unit Test Report'
|
||||
DEFAULT_TITLE = '测试报告'
|
||||
DEFAULT_DESCRIPTION = ''
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
@@ -206,6 +205,7 @@ class Template_mixin(object):
|
||||
<title>%(title)s</title>
|
||||
<meta name="generator" content="%(generator)s"/>
|
||||
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
||||
%(stylesheet)s
|
||||
|
||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||
@@ -213,15 +213,328 @@ class Template_mixin(object):
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<script language="javascript" type="text/javascript"><!--
|
||||
<div class="container">
|
||||
%(heading)s
|
||||
%(report)s
|
||||
%(ending)s
|
||||
</div>
|
||||
%(scripts)s
|
||||
"""
|
||||
# variables: (title, generator, stylesheet, heading, report, ending)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Stylesheet
|
||||
#
|
||||
# alternatively use a <link> for external style sheet, e.g.
|
||||
# <link rel="stylesheet" href="$url" type="text/css">
|
||||
|
||||
STYLESHEET_TMPL = """
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
/* -- css div popup ------------------------------------------------------------------------ */
|
||||
.popup_window {
|
||||
display: none;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
/*border: solid #627173 1px; */
|
||||
padding: 10px;
|
||||
background-color: #99CCFF;
|
||||
font-family: "Lucida Console", "Courier New", Courier, monospace;
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
|
||||
#show_detail_line .label {
|
||||
font-size: 85%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#show_detail_line {
|
||||
margin: 2em auto 1em auto;
|
||||
}
|
||||
|
||||
#total_row { font-weight: bold; }
|
||||
.hiddenRow { display: none; }
|
||||
.testcase { margin-left: 2em; }
|
||||
|
||||
</style>
|
||||
"""
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Heading
|
||||
#
|
||||
|
||||
HEADING_TMPL = """<div class='heading'>
|
||||
<div >
|
||||
<h1>%(title)s</h1>
|
||||
%(parameters)s
|
||||
<p class='description'>%(description)s</p>
|
||||
</div> </div >
|
||||
"""
|
||||
HEADING_TMPL_New="""
|
||||
<div class='heading'>
|
||||
<div style='width: 50%%;float:left;margin-top:inherit'>
|
||||
<h1>%(title)s</h1>
|
||||
%(parameters)s
|
||||
<p class='description'>%(description)s</p>
|
||||
</div>
|
||||
|
||||
<div id='container2' style='width:50%%;float:left;margin-top:20px;height:200px;'>
|
||||
</div>
|
||||
</div >
|
||||
<div id='containerchart' style='height: 300px;margin-top: 20%%;'></div>
|
||||
"""
|
||||
HEADING_OLD = """<div class='heading'>
|
||||
<h1>%(title)s</h1>
|
||||
%(parameters)s
|
||||
<p class='description'>%(description)s</p>
|
||||
</div>
|
||||
"""
|
||||
HEADING_ATTRIBUTE_TMPL = """<p><strong>%(name)s:</strong> %(value)s</p>
|
||||
""" # variables: (name, value)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Report
|
||||
#
|
||||
|
||||
REPORT_TMPL = """
|
||||
<p id='show_detail_line'>
|
||||
<span class="label label-primary" onclick="showCase(0)">公用</span>
|
||||
<span class="label label-danger" onclick="showCase(1)">失败</span>
|
||||
<span class="label label-default" onclick="showCase(2)">所有</span>
|
||||
</p>
|
||||
<table id='result_table' class="table">
|
||||
<thead>
|
||||
<tr id='header_row'>
|
||||
<th>测试组/测试用例</td>
|
||||
<th>数量</td>
|
||||
<th>失败</td>
|
||||
<th>通过</td>
|
||||
<th>错误</td>
|
||||
<th>查看</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%(test_list)s
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id='total_row'>
|
||||
<td>总计</td>
|
||||
<td>%(count)s</td>
|
||||
<td class="text text-success">%(Pass)s</td>
|
||||
<td class="text text-danger">%(fail)s</td>
|
||||
<td class="text text-warning">%(error)s</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
""" # variables: (test_list, count, Pass, fail, error)
|
||||
|
||||
REPORT_CLASS_TMPL = r"""
|
||||
<tr class='%(style)s'>
|
||||
<td>%(desc)s</td>
|
||||
<td>%(count)s</td>
|
||||
<td>%(Pass)s</td>
|
||||
<td>%(fail)s</td>
|
||||
<td>%(error)s</td>
|
||||
<td><a class="btn btn-xs btn-primary"href="javascript:showClassDetail('%(cid)s',%(count)s)">详情</a></td>
|
||||
</tr>
|
||||
""" # variables: (style, desc, count, Pass, fail, error, cid)
|
||||
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL = r"""
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();' href="javascript:showTestDetail('div_%(tid)s')" >
|
||||
%(status)s</a>
|
||||
|
||||
<div id='div_%(tid)s' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();' onclick="document.getElementById('div_%(tid)s').style.display = 'none' " >
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
%(script)s
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
REPORT_TEST_NO_OUTPUT_TMPL = r"""
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
|
||||
<td colspan='5' align='center'>%(status)s</td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
REPORT_TEST_OUTPUT_TMPL = r"""
|
||||
%(id)s: %(output)s
|
||||
""" # variables: (id, output)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# ENDING
|
||||
#
|
||||
|
||||
ENDING_TMPL = """<div id='ending'> </div>"""
|
||||
SCRPICTold="""
|
||||
<script language='javascript' type='text/javascript'>
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName('tr');
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
if (id.substr(0,2) == 'ft') {
|
||||
if (level < 1) {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
else {
|
||||
tr.className = '';
|
||||
}
|
||||
}
|
||||
if (id.substr(0,2) == 'pt') {
|
||||
if (level > 1) {
|
||||
tr.className = '';
|
||||
}
|
||||
else {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showClassDetail(cid, count) {
|
||||
var id_list = Array(count);
|
||||
var toHide = 1;
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid0 = 't' + cid.substr(1) + '.' + (i+1);
|
||||
tid = 'f' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
if (!tr) {
|
||||
tid = 'p' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
}
|
||||
id_list[i] = tid;
|
||||
if (tr.className) {
|
||||
toHide = 0;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid = id_list[i];
|
||||
if (toHide) {
|
||||
document.getElementById('div_'+tid).style.display = 'none'
|
||||
document.getElementById(tid).className = 'hiddenRow';
|
||||
}
|
||||
else {
|
||||
document.getElementById(tid).className = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
function showTestDetail(div_id){
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
if (displayState != 'block' ) {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
}
|
||||
else {
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g,'&');
|
||||
s = s.replace(/</g,'<');
|
||||
s = s.replace(/>/g,'>');
|
||||
return s;
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
SCRPICTDATA=r"""
|
||||
<script language='javascript' type='text/javascript'>
|
||||
var dom = document.getElementById('containerchart');
|
||||
var myChart = echarts.init(dom);
|
||||
var domone = document.getElementById('container2');
|
||||
var myChartone = echarts.init(domone);
|
||||
var optionsone;
|
||||
optionsone = {
|
||||
title: {
|
||||
text: '历史记录'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['成功', '失败','错误']
|
||||
},
|
||||
grid: {
|
||||
left: '3%%',
|
||||
right: '4%%',
|
||||
bottom: '3%%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: %(reslutname)s
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '成功',
|
||||
type: 'line',
|
||||
stack: '总量',
|
||||
data: %(success)s
|
||||
},
|
||||
{
|
||||
name: '失败',
|
||||
type: 'line',
|
||||
stack: '总量',
|
||||
data: %(fail)s
|
||||
},
|
||||
{
|
||||
name: '错误',
|
||||
type: 'line',
|
||||
stack: '总量',
|
||||
data: %(error)s
|
||||
}
|
||||
|
||||
]
|
||||
};
|
||||
if (optionsone && typeof optionsone === 'object') {
|
||||
myChartone.setOption(optionsone);
|
||||
}
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName("tr");
|
||||
trs = document.getElementsByTagName('tr');
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
@@ -277,7 +590,6 @@ function showClassDetail(cid, count) {
|
||||
function showTestDetail(div_id){
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
// alert(displayState)
|
||||
if (displayState != 'block' ) {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
@@ -286,200 +598,23 @@ function showTestDetail(div_id){
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g,'&');
|
||||
s = s.replace(/</g,'<');
|
||||
s = s.replace(/>/g,'>');
|
||||
return s;
|
||||
}
|
||||
|
||||
/* obsoleted by detail in <div>
|
||||
function showOutput(id, name) {
|
||||
var w = window.open("", //url
|
||||
name,
|
||||
"resizable,scrollbars,status,width=800,height=450");
|
||||
d = w.document;
|
||||
d.write("<pre>");
|
||||
d.write(html_escape(output_list[id]));
|
||||
d.write("\n");
|
||||
d.write("<a href='javascript:window.close()'>close</a>\n");
|
||||
d.write("</pre>\n");
|
||||
d.close();
|
||||
}
|
||||
*/
|
||||
--></script>
|
||||
|
||||
<div class="container">
|
||||
%(heading)s
|
||||
%(report)s
|
||||
%(ending)s
|
||||
</div>
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
# variables: (title, generator, stylesheet, heading, report, ending)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Stylesheet
|
||||
#
|
||||
# alternatively use a <link> for external style sheet, e.g.
|
||||
# <link rel="stylesheet" href="$url" type="text/css">
|
||||
|
||||
STYLESHEET_TMPL = """
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
/* -- css div popup ------------------------------------------------------------------------ */
|
||||
.popup_window {
|
||||
display: none;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
/*border: solid #627173 1px; */
|
||||
padding: 10px;
|
||||
background-color: #99CCFF;
|
||||
font-family: "Lucida Console", "Courier New", Courier, monospace;
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
|
||||
#show_detail_line .label {
|
||||
font-size: 85%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#show_detail_line {
|
||||
margin: 2em auto 1em auto;
|
||||
}
|
||||
|
||||
#total_row { font-weight: bold; }
|
||||
.hiddenRow { display: none; }
|
||||
.testcase { margin-left: 2em; }
|
||||
|
||||
</style>
|
||||
"""
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Heading
|
||||
#
|
||||
|
||||
HEADING_TMPL = """<div class='heading'>
|
||||
<h1>%(title)s</h1>
|
||||
%(parameters)s
|
||||
<p class='description'>%(description)s</p>
|
||||
</div>
|
||||
|
||||
""" # variables: (title, parameters, description)
|
||||
|
||||
HEADING_ATTRIBUTE_TMPL = """<p><strong>%(name)s:</strong> %(value)s</p>
|
||||
""" # variables: (name, value)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Report
|
||||
#
|
||||
|
||||
REPORT_TMPL = """
|
||||
<p id='show_detail_line'>
|
||||
<span class="label label-primary" onclick="showCase(0)">Summary</span>
|
||||
<span class="label label-danger" onclick="showCase(1)">Failed</span>
|
||||
<span class="label label-default" onclick="showCase(2)">All</span>
|
||||
</p>
|
||||
<table id='result_table' class="table">
|
||||
<thead>
|
||||
<tr id='header_row'>
|
||||
<th>Test Group/Test case</td>
|
||||
<th>Count</td>
|
||||
<th>Pass</td>
|
||||
<th>Fail</td>
|
||||
<th>Error</td>
|
||||
<th>View</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
%(test_list)s
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id='total_row'>
|
||||
<td>Total</td>
|
||||
<td>%(count)s</td>
|
||||
<td class="text text-success">%(Pass)s</td>
|
||||
<td class="text text-danger">%(fail)s</td>
|
||||
<td class="text text-warning">%(error)s</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
""" # variables: (test_list, count, Pass, fail, error)
|
||||
|
||||
REPORT_CLASS_TMPL = r"""
|
||||
<tr class='%(style)s'>
|
||||
<td>%(desc)s</td>
|
||||
<td>%(count)s</td>
|
||||
<td>%(Pass)s</td>
|
||||
<td>%(fail)s</td>
|
||||
<td>%(error)s</td>
|
||||
<td><a class="btn btn-xs btn-primary"href="javascript:showClassDetail('%(cid)s',%(count)s)">Detail</a></td>
|
||||
</tr>
|
||||
""" # variables: (style, desc, count, Pass, fail, error, cid)
|
||||
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL = r"""
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();' href="javascript:showTestDetail('div_%(tid)s')" >
|
||||
%(status)s</a>
|
||||
|
||||
<div id='div_%(tid)s' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();' onclick="document.getElementById('div_%(tid)s').style.display = 'none' " >
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
%(script)s
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
REPORT_TEST_NO_OUTPUT_TMPL = r"""
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s'><div class='testcase'>%(desc)s</div></td>
|
||||
<td colspan='5' align='center'>%(status)s</td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
REPORT_TEST_OUTPUT_TMPL = r"""
|
||||
%(id)s: %(output)s
|
||||
""" # variables: (id, output)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# ENDING
|
||||
#
|
||||
|
||||
ENDING_TMPL = """<div id='ending'> </div>"""
|
||||
|
||||
|
||||
"""
|
||||
# -------------------- 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):
|
||||
class MyResult(TestResult):
|
||||
def __init__(self, verbosity=1, trynum=1):
|
||||
# 默认次数是0
|
||||
TestResult.__init__(self)
|
||||
self.outputBuffer = StringIO()
|
||||
self.stdout0 = None
|
||||
@@ -488,32 +623,17 @@ class _TestResult(TestResult):
|
||||
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.trynnum = trynum
|
||||
self.result = []
|
||||
self.trys = 0 #
|
||||
self.istry = False
|
||||
|
||||
def startTest(self, test):
|
||||
TestResult.startTest(self, test)
|
||||
# just one buffer for both stdout and stderr 更改
|
||||
self.outputBuffer = 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_redirector
|
||||
|
||||
def 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
|
||||
@@ -522,12 +642,33 @@ class _TestResult(TestResult):
|
||||
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.
|
||||
# 判断是否要重试
|
||||
if self.istry is True:
|
||||
# 如果执行的次数小于重试的次数 就重试
|
||||
if self.trys < self.trynnum:
|
||||
# 删除最后一个结果
|
||||
reslut = self.result.pop(-1)
|
||||
# 判断结果,如果是错误就把错误的个数减掉
|
||||
# 如果是失败,就把失败的次数减掉
|
||||
if reslut[0] == 1:
|
||||
self.failure_count -= 1
|
||||
else:
|
||||
self.error_count -= 1
|
||||
sys.stderr.write('{}:用例正在重试中。。。'.format(test.id()) + '\n')
|
||||
# 深copy用例
|
||||
test = copy.copy(test)
|
||||
# 重试次数增加+1
|
||||
self.trys += 1
|
||||
# 测试
|
||||
test(self)
|
||||
else:
|
||||
self.istry = False
|
||||
self.trys = 0
|
||||
self.complete_output()
|
||||
|
||||
def addSuccess(self, test):
|
||||
# 成功就不要重试
|
||||
self.istry = False
|
||||
self.success_count += 1
|
||||
TestResult.addSuccess(self, test)
|
||||
output = self.complete_output()
|
||||
@@ -540,6 +681,8 @@ class _TestResult(TestResult):
|
||||
sys.stderr.write('.')
|
||||
|
||||
def addError(self, test, err):
|
||||
# 重试+1,错误次数+1
|
||||
self.istry = True
|
||||
self.error_count += 1
|
||||
TestResult.addError(self, test, err)
|
||||
_, _exc_str = self.errors[-1]
|
||||
@@ -553,6 +696,8 @@ class _TestResult(TestResult):
|
||||
sys.stderr.write('E')
|
||||
|
||||
def addFailure(self, test, err):
|
||||
self.istry = True
|
||||
TestResult.startTestRun(self)
|
||||
self.failure_count += 1
|
||||
TestResult.addFailure(self, test, err)
|
||||
_, _exc_str = self.failures[-1]
|
||||
@@ -565,14 +710,36 @@ class _TestResult(TestResult):
|
||||
else:
|
||||
sys.stderr.write('F')
|
||||
|
||||
def stop(self) -> None:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class _TestResult(MyResult):
|
||||
# note: _TestResult is a pure representation of results.
|
||||
# It lacks the output and reporting ability compares to unittest._TextTestResult.
|
||||
|
||||
def __init__(self, verbosity=1, trynum=1):
|
||||
TestResult.__init__(self)
|
||||
super().__init__(verbosity, trynum)
|
||||
|
||||
|
||||
class BSTestRunner(Template_mixin):
|
||||
"""
|
||||
"""
|
||||
|
||||
def __init__(self, stream=sys.stdout, verbosity=1, title=None, description=None):
|
||||
def __init__(self, stream=sys.stdout,
|
||||
verbosity=1,
|
||||
title=None,
|
||||
description=None,
|
||||
trynum=1,
|
||||
is_show=False,
|
||||
filepath=""):
|
||||
self.stream = stream
|
||||
self.verbosity = verbosity
|
||||
self.trynum = trynum
|
||||
self.is_show=is_show
|
||||
self.filepath=filepath
|
||||
if title is None:
|
||||
self.title = self.DEFAULT_TITLE
|
||||
else:
|
||||
@@ -586,12 +753,17 @@ class BSTestRunner(Template_mixin):
|
||||
|
||||
def run(self, test):
|
||||
"Run the given test case or test suite."
|
||||
result = _TestResult(self.verbosity)
|
||||
result = _TestResult(self.verbosity, trynum=self.trynum)
|
||||
try:
|
||||
test(result)
|
||||
except TypeError:
|
||||
pass
|
||||
self.stopTime = datetime.datetime.now()
|
||||
if self.is_show:
|
||||
name=os.path.join(self.filepath,self.stopTime.strftime('%Y_%m_%d_%H_%M_%S')+'.txt')
|
||||
with open(name,'w+') as f:
|
||||
f.write(result.success_count.__str__()+"_"+result.error_count.__str__()+"_"+result.failure_count.__str__())
|
||||
f.close()
|
||||
self.generateReport(test, result)
|
||||
print('\n测试耗时: %s' % (self.stopTime - self.startTime))
|
||||
return result
|
||||
@@ -619,19 +791,19 @@ class BSTestRunner(Template_mixin):
|
||||
duration = str(self.stopTime - self.startTime)
|
||||
status = []
|
||||
if result.success_count: status.append(
|
||||
'<span class="text text-success">Pass <strong>%s</strong></span>' % result.success_count)
|
||||
'<span class="text text-success">通过 <strong>%s</strong></span>' % result.success_count)
|
||||
if result.failure_count: status.append(
|
||||
'<span class="text text-danger">Failure <strong>%s</strong></span>' % result.failure_count)
|
||||
'<span class="text text-danger">失败 <strong>%s</strong></span>' % result.failure_count)
|
||||
if result.error_count: status.append(
|
||||
'<span class="text text-warning">Error <strong>%s</strong></span>' % result.error_count)
|
||||
'<span class="text text-warning">错误 <strong>%s</strong></span>' % result.error_count)
|
||||
if status:
|
||||
status = ' '.join(status)
|
||||
else:
|
||||
status = 'none'
|
||||
return [
|
||||
('Start Time', startTime),
|
||||
('Duration', duration),
|
||||
('Status', status),
|
||||
('开始时间', startTime),
|
||||
('持续时间', duration),
|
||||
('状态', status),
|
||||
]
|
||||
|
||||
def generateReport(self, test, result):
|
||||
@@ -641,35 +813,62 @@ class BSTestRunner(Template_mixin):
|
||||
heading = self._generate_heading(report_attrs)
|
||||
report = self._generate_report(result)
|
||||
ending = self._generate_ending()
|
||||
if self.is_show:
|
||||
scrpit=self.___generate_scrpitone()
|
||||
else:
|
||||
scrpit=self._generate_scrpit()
|
||||
output = self.HTML_TMPL % dict(
|
||||
title=saxutils.escape(self.title),
|
||||
generator=generator,
|
||||
stylesheet=stylesheet,
|
||||
scripts=scrpit,
|
||||
heading=heading,
|
||||
report=report,
|
||||
ending=ending,
|
||||
ending=ending
|
||||
)
|
||||
self.stream.write(output.encode('utf-8'))
|
||||
self.stream.write(output.encode("utf-8"))
|
||||
|
||||
def _generate_stylesheet(self):
|
||||
return self.STYLESHEET_TMPL
|
||||
|
||||
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),
|
||||
ISSHOWPERDATA=True
|
||||
if ISSHOWPERDATA:
|
||||
a_lines = []
|
||||
for name, value in report_attrs:
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name=saxutils.escape(name), ####更改
|
||||
# value = saxutils.escape(value),
|
||||
|
||||
value=value,
|
||||
value=value,
|
||||
)
|
||||
a_lines.append(line)
|
||||
if self.is_show:
|
||||
heading = self.HEADING_TMPL_New % dict(
|
||||
title=saxutils.escape(self.title),parameters=''.join(a_lines),description=saxutils.escape(self.description),)
|
||||
else:
|
||||
heading = self.HEADING_TMPL % dict(
|
||||
title=saxutils.escape(self.title),
|
||||
parameters=''.join(a_lines),
|
||||
description=saxutils.escape(self.description),
|
||||
)
|
||||
return heading
|
||||
else:
|
||||
a_lines = []
|
||||
for name, value in report_attrs:
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name=saxutils.escape(name), ####更改
|
||||
# value = saxutils.escape(value),
|
||||
|
||||
value=value,
|
||||
)
|
||||
a_lines.append(line)
|
||||
heading = self.HEADING_OLD % dict(
|
||||
title=saxutils.escape(self.title),
|
||||
parameters=''.join(a_lines),
|
||||
description=saxutils.escape(self.description),
|
||||
)
|
||||
a_lines.append(line)
|
||||
heading = self.HEADING_TMPL % dict(
|
||||
title=saxutils.escape(self.title),
|
||||
parameters=''.join(a_lines),
|
||||
description=saxutils.escape(self.description),
|
||||
)
|
||||
return heading
|
||||
return heading
|
||||
|
||||
def _generate_report(self, result):
|
||||
rows = []
|
||||
@@ -760,6 +959,29 @@ class BSTestRunner(Template_mixin):
|
||||
|
||||
def _generate_ending(self):
|
||||
return self.ENDING_TMPL
|
||||
def ___generate_scrpitone(self):
|
||||
namerun,faillist,success,error=self._readresult()
|
||||
return self.SCRPICTDATA% dict(reslutname=namerun,
|
||||
success=success,
|
||||
fail=faillist,
|
||||
error=error)
|
||||
def _readresult(self):
|
||||
namerun=[]
|
||||
faillist=[]
|
||||
success=[]
|
||||
error=[]
|
||||
for root,dirs,files in os.walk(self.filepath):
|
||||
for file in files:
|
||||
if file.endswith(".txt"):
|
||||
namerun.append(file.split(".")[0].split("/")[-1])
|
||||
with open(os.path.join(root,file),'r') as f:
|
||||
reslut=f.readline().split('\n')[0].split("_")
|
||||
success.append(reslut[0])
|
||||
error.append(reslut[1])
|
||||
faillist.append(reslut[2])
|
||||
return namerun,faillist,success,error
|
||||
def _generate_scrpit(self):
|
||||
return self.SCRPICTold
|
||||
|
||||
|
||||
##############################################################################
|
||||
@@ -790,5 +1012,4 @@ main = TestProgram
|
||||
# Executing this module from the command line
|
||||
##############################################################################
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(module=None)
|
||||
|
||||
|
||||
11
run_new.py
11
run_new.py
@@ -3,7 +3,7 @@
|
||||
from testCase.ddt_case import MyTest
|
||||
import unittest, time, os
|
||||
from Public import BSTestRunner
|
||||
|
||||
BASH_DIR="history"
|
||||
if __name__ == '__main__':
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(MyTest))
|
||||
@@ -12,5 +12,10 @@ if __name__ == '__main__':
|
||||
file_dir = os.path.join(basedir, 'test_Report')
|
||||
file = os.path.join(file_dir, (now + '.html'))
|
||||
re_open = open(file, 'wb')
|
||||
runner = BSTestRunner.BSTestRunner(stream=re_open, title='接口测试报告', description='测试结果')
|
||||
runner.run(suite)
|
||||
besautiful = BSTestRunner.BSTestRunner(title="报告",
|
||||
description="测试报告",
|
||||
stream=re_open,
|
||||
trynum=3,
|
||||
filepath=BASH_DIR,
|
||||
is_show=True)
|
||||
besautiful.run(suite)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from Interface.testFengzhuang import TestApi
|
||||
from Public.get_excel import datacel, makedata
|
||||
from Public.log import LOG, logger
|
||||
from Public.get_excel import makedata
|
||||
from Public.log import LOG
|
||||
from Public.panduan import assertre
|
||||
import ddt, unittest, time, os
|
||||
import ddt, unittest
|
||||
|
||||
data_test = makedata()
|
||||
|
||||
@@ -25,5 +25,5 @@ class MyTest(unittest.TestCase):
|
||||
data_test['fangshi']))))
|
||||
apijson = api.getJson()
|
||||
LOG.info('返回结果:%s' % apijson)
|
||||
qingwang = assertre(asserqingwang=data_test['qiwang'])
|
||||
self.assertNotEqual(dict(qingwang), dict(apijson), msg='预期和返回不一致')
|
||||
assertall = assertre(asserqingwang=data_test['qiwang'])
|
||||
self.assertNotEqual(dict(assertall), dict(apijson), msg='预期和返回不一致')
|
||||
|
||||
@@ -1,328 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title>接口测试报告</title>
|
||||
<meta name="generator" content="BSTestRunner 0.8.4"/>
|
||||
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
/* -- css div popup ------------------------------------------------------------------------ */
|
||||
.popup_window {
|
||||
display: none;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
/*border: solid #627173 1px; */
|
||||
padding: 10px;
|
||||
background-color: #99CCFF;
|
||||
font-family: "Lucida Console", "Courier New", Courier, monospace;
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
|
||||
#show_detail_line .label {
|
||||
font-size: 85%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#show_detail_line {
|
||||
margin: 2em auto 1em auto;
|
||||
}
|
||||
|
||||
#total_row {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hiddenRow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.testcase {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<script language="javascript" type="text/javascript"><!--
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName("tr");
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
if (id.substr(0, 2) == 'ft') {
|
||||
if (level < 1) {
|
||||
tr.className = 'hiddenRow';
|
||||
} else {
|
||||
tr.className = '';
|
||||
}
|
||||
}
|
||||
if (id.substr(0, 2) == 'pt') {
|
||||
if (level > 1) {
|
||||
tr.className = '';
|
||||
} else {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showClassDetail(cid, count) {
|
||||
var id_list = Array(count);
|
||||
var toHide = 1;
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid0 = 't' + cid.substr(1) + '.' + (i + 1);
|
||||
tid = 'f' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
if (!tr) {
|
||||
tid = 'p' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
}
|
||||
id_list[i] = tid;
|
||||
if (tr.className) {
|
||||
toHide = 0;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid = id_list[i];
|
||||
if (toHide) {
|
||||
document.getElementById('div_' + tid).style.display = 'none'
|
||||
document.getElementById(tid).className = 'hiddenRow';
|
||||
} else {
|
||||
document.getElementById(tid).className = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showTestDetail(div_id) {
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
// alert(displayState)
|
||||
if (displayState != 'block') {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
} else {
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g, '&');
|
||||
s = s.replace(/</g, '<');
|
||||
s = s.replace(/>/g, '>');
|
||||
return s;
|
||||
}
|
||||
|
||||
/* obsoleted by detail in <div>
|
||||
function showOutput(id, name) {
|
||||
var w = window.open("", //url
|
||||
name,
|
||||
"resizable,scrollbars,status,width=800,height=450");
|
||||
d = w.document;
|
||||
d.write("<pre>");
|
||||
d.write(html_escape(output_list[id]));
|
||||
d.write("\n");
|
||||
d.write("<a href='javascript:window.close()'>close</a>\n");
|
||||
d.write("</pre>\n");
|
||||
d.close();
|
||||
}
|
||||
*/
|
||||
--></script>
|
||||
|
||||
<div class="container">
|
||||
<div class='heading'>
|
||||
<h1>接口测试报告</h1>
|
||||
<p><strong>Start Time:</strong> 2017-11-01 10:25:40</p>
|
||||
<p><strong>Duration:</strong> 0:00:00.070004</p>
|
||||
<p><strong>Status:</strong> <span class="text text-success">Pass <strong>2</strong></span> <span
|
||||
class="text text-warning">Error <strong>1</strong></span></p>
|
||||
|
||||
<p class='description'>测试结果</p>
|
||||
</div>
|
||||
|
||||
|
||||
<p id='show_detail_line'>
|
||||
<span class="label label-primary" onclick="showCase(0)">Summary</span>
|
||||
<span class="label label-danger" onclick="showCase(1)">Failed</span>
|
||||
<span class="label label-default" onclick="showCase(2)">All</span>
|
||||
</p>
|
||||
<table id='result_table' class="table">
|
||||
<thead>
|
||||
<tr id='header_row'>
|
||||
<th>Test Group/Test case
|
||||
</td>
|
||||
<th>Count
|
||||
</td>
|
||||
<th>Pass
|
||||
</td>
|
||||
<th>Fail
|
||||
</td>
|
||||
<th>Error
|
||||
</td>
|
||||
<th>View
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr class='text text-warning'>
|
||||
<td>testCase.ddt_case.MyTest</td>
|
||||
<td>3</td>
|
||||
<td>2</td>
|
||||
<td>0</td>
|
||||
<td>1</td>
|
||||
<td><a class="btn btn-xs btn-primary" href="javascript:showClassDetail('c1',3)">Detail</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.1' class='hiddenRow'>
|
||||
<td class='text text-success'>
|
||||
<div class='testcase'>test_api_1</div>
|
||||
</td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();'
|
||||
href="javascript:showTestDetail('div_pt1.1')">
|
||||
pass</a>
|
||||
|
||||
<div id='div_pt1.1' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();'
|
||||
onclick="document.getElementById('div_pt1.1').style.display = 'none' ">
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
pt1.1: [2017-11-01 10:25:40.109053] INFO: jiekou: 测试用例开始执行
|
||||
[2017-11-01 10:25:40.109053] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api,key:aaaa,参数:sasa,请求方式:POST
|
||||
[2017-11-01 10:25:40.109053] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api,key:aaaa,参数:sasa,请求方式:None
|
||||
[2017-11-01 10:25:40.143055] INFO: jiekou: 返回结果:{'code': 40001, 'text': '亲爱的,key不对哦。'}
|
||||
[2017-11-01 10:25:40.143055] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2017-11-01 10:25:40.144055] INFO: jiekou: 测试用例执行完毕
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.2' class='hiddenRow'>
|
||||
<td class='text text-success'>
|
||||
<div class='testcase'>test_api_2</div>
|
||||
</td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();'
|
||||
href="javascript:showTestDetail('div_pt1.2')">
|
||||
pass</a>
|
||||
|
||||
<div id='div_pt1.2' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();'
|
||||
onclick="document.getElementById('div_pt1.2').style.display = 'none' ">
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
pt1.2: [2017-11-01 10:25:40.144055] INFO: jiekou: 测试用例开始执行
|
||||
[2017-11-01 10:25:40.144055] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api
|
||||
,key:dfeb1cc8125943d29764a2f2f5c33739,参数:,请求方式:POST
|
||||
[2017-11-01 10:25:40.144055] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api
|
||||
,key:dfeb1cc8125943d29764a2f2f5c33739,参数:,请求方式:None
|
||||
[2017-11-01 10:25:40.177057] INFO: jiekou: 返回结果:{'code': 40002, 'text': 'what?'}
|
||||
[2017-11-01 10:25:40.177057] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2017-11-01 10:25:40.178057] INFO: jiekou: 测试用例执行完毕
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id='ft1.3' class='none'>
|
||||
<td class='text text-warning'>
|
||||
<div class='testcase'>test_api_3</div>
|
||||
</td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();'
|
||||
href="javascript:showTestDetail('div_ft1.3')">
|
||||
error</a>
|
||||
|
||||
<div id='div_ft1.3' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();'
|
||||
onclick="document.getElementById('div_ft1.3').style.display = 'none' ">
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
ft1.3: [2017-11-01 10:25:40.178057] INFO: jiekou: 测试用例开始执行
|
||||
[2017-11-01 10:25:40.178057] INFO: jiekou: 输入参数:url:https://api.douban.com/v2/photo/:id,key:,参数:,请求方式:GET
|
||||
[2017-11-01 10:25:40.178057] INFO: jiekou: 输入参数:url:https://api.douban.com/v2/photo/:id,key:,参数:,请求方式:None
|
||||
[2017-11-01 10:25:40.178057] INFO: jiekou: 测试用例执行完毕
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\Administrator\AppData\Roaming\Python\Python36\site-packages\ddt.py", line 139, in wrapper
|
||||
return func(self, *args, **kwargs)
|
||||
File "C:\Users\Administrator\Desktop\jiekou-python3\testCase\ddt_case.py", line 17, in test_api
|
||||
apijson = api.getJson()
|
||||
File "C:\Users\Administrator\Desktop\jiekou-python3\Interface\testFengzhuang.py", line 27, in getJson
|
||||
json_data = self.testapi()
|
||||
File "C:\Users\Administrator\Desktop\jiekou-python3\Interface\testFengzhuang.py", line 21, in testapi
|
||||
response = reques.get(self.url,self.parem)
|
||||
TypeError: get() takes 2 positional arguments but 3 were given
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id='total_row'>
|
||||
<td>Total</td>
|
||||
<td>3</td>
|
||||
<td class="text text-success">2</td>
|
||||
<td class="text text-danger">0</td>
|
||||
<td class="text text-warning">1</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div id='ending'> </div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
@@ -1,337 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title>http接口测试报告</title>
|
||||
<meta name="generator" content="BSTestRunner 0.8.4"/>
|
||||
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
/* -- css div popup ------------------------------------------------------------------------ */
|
||||
.popup_window {
|
||||
display: none;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
/*border: solid #627173 1px; */
|
||||
padding: 10px;
|
||||
background-color: #99CCFF;
|
||||
font-family: "Lucida Console", "Courier New", Courier, monospace;
|
||||
text-align: left;
|
||||
font-size: 10pt;
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
|
||||
#show_detail_line .label {
|
||||
font-size: 85%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#show_detail_line {
|
||||
margin: 2em auto 1em auto;
|
||||
}
|
||||
|
||||
#total_row {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hiddenRow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.testcase {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||||
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<script language="javascript" type="text/javascript"><!--
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName("tr");
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
if (id.substr(0, 2) == 'ft') {
|
||||
if (level < 1) {
|
||||
tr.className = 'hiddenRow';
|
||||
} else {
|
||||
tr.className = '';
|
||||
}
|
||||
}
|
||||
if (id.substr(0, 2) == 'pt') {
|
||||
if (level > 1) {
|
||||
tr.className = '';
|
||||
} else {
|
||||
tr.className = 'hiddenRow';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showClassDetail(cid, count) {
|
||||
var id_list = Array(count);
|
||||
var toHide = 1;
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid0 = 't' + cid.substr(1) + '.' + (i + 1);
|
||||
tid = 'f' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
if (!tr) {
|
||||
tid = 'p' + tid0;
|
||||
tr = document.getElementById(tid);
|
||||
}
|
||||
id_list[i] = tid;
|
||||
if (tr.className) {
|
||||
toHide = 0;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < count; i++) {
|
||||
tid = id_list[i];
|
||||
if (toHide) {
|
||||
document.getElementById('div_' + tid).style.display = 'none'
|
||||
document.getElementById(tid).className = 'hiddenRow';
|
||||
} else {
|
||||
document.getElementById(tid).className = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showTestDetail(div_id) {
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
// alert(displayState)
|
||||
if (displayState != 'block') {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
} else {
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g, '&');
|
||||
s = s.replace(/</g, '<');
|
||||
s = s.replace(/>/g, '>');
|
||||
return s;
|
||||
}
|
||||
|
||||
/* obsoleted by detail in <div>
|
||||
function showOutput(id, name) {
|
||||
var w = window.open("", //url
|
||||
name,
|
||||
"resizable,scrollbars,status,width=800,height=450");
|
||||
d = w.document;
|
||||
d.write("<pre>");
|
||||
d.write(html_escape(output_list[id]));
|
||||
d.write("\n");
|
||||
d.write("<a href='javascript:window.close()'>close</a>\n");
|
||||
d.write("</pre>\n");
|
||||
d.close();
|
||||
}
|
||||
*/
|
||||
--></script>
|
||||
|
||||
<div class="container">
|
||||
<div class='heading'>
|
||||
<h1>http接口测试报告</h1>
|
||||
<p><strong>Start Time:</strong> 2018-04-02 10:53:02</p>
|
||||
<p><strong>Duration:</strong> 0:00:02.914166</p>
|
||||
<p><strong>Status:</strong> <span class="text text-success">Pass <strong>2</strong></span> <span
|
||||
class="text text-warning">Error <strong>1</strong></span></p>
|
||||
|
||||
<p class='description'>测试结果</p>
|
||||
</div>
|
||||
|
||||
|
||||
<p id='show_detail_line'>
|
||||
<span class="label label-primary" onclick="showCase(0)">Summary</span>
|
||||
<span class="label label-danger" onclick="showCase(1)">Failed</span>
|
||||
<span class="label label-default" onclick="showCase(2)">All</span>
|
||||
</p>
|
||||
<table id='result_table' class="table">
|
||||
<thead>
|
||||
<tr id='header_row'>
|
||||
<th>Test Group/Test case
|
||||
</td>
|
||||
<th>Count
|
||||
</td>
|
||||
<th>Pass
|
||||
</td>
|
||||
<th>Fail
|
||||
</td>
|
||||
<th>Error
|
||||
</td>
|
||||
<th>View
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr class='text text-warning'>
|
||||
<td>testCase.ddt_case.MyTest</td>
|
||||
<td>3</td>
|
||||
<td>2</td>
|
||||
<td>0</td>
|
||||
<td>1</td>
|
||||
<td><a class="btn btn-xs btn-primary" href="javascript:showClassDetail('c1',3)">Detail</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.1' class='hiddenRow'>
|
||||
<td class='text text-success'>
|
||||
<div class='testcase'>test_api_1</div>
|
||||
</td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();'
|
||||
href="javascript:showTestDetail('div_pt1.1')">
|
||||
pass</a>
|
||||
|
||||
<div id='div_pt1.1' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();'
|
||||
onclick="document.getElementById('div_pt1.1').style.display = 'none' ">
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
pt1.1: [2018-04-02 10:53:02.332375] INFO: jiekou: 测试用例开始执行
|
||||
[2018-04-02 10:53:02.332375] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:POST
|
||||
[2018-04-02 10:53:02.332375] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:None
|
||||
[2018-04-02 10:53:02.364376] INFO: jiekou: 返回结果:{'code': 0, 'result': {'code': 40007, 'text': '您的请求内容为空。'}}
|
||||
[2018-04-02 10:53:02.364376] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2018-04-02 10:53:02.364376] INFO: jiekou: 全部args参数参数信息 , ()
|
||||
[2018-04-02 10:53:02.364376] INFO: jiekou: 全部kwargs参数信息 , {'asserqingwang': 'code=40001'}
|
||||
[2018-04-02 10:53:02.364376] INFO: jiekou: 测试用例执行完毕
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.2' class='hiddenRow'>
|
||||
<td class='text text-success'>
|
||||
<div class='testcase'>test_api_2</div>
|
||||
</td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();'
|
||||
href="javascript:showTestDetail('div_pt1.2')">
|
||||
pass</a>
|
||||
|
||||
<div id='div_pt1.2' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();'
|
||||
onclick="document.getElementById('div_pt1.2').style.display = 'none' ">
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
pt1.2: [2018-04-02 10:53:02.364376] INFO: jiekou: 测试用例开始执行
|
||||
[2018-04-02 10:53:02.364376] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api
|
||||
,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:POST
|
||||
[2018-04-02 10:53:02.365376] INFO: jiekou: 输入参数:url:http://www.tuling123.com/openapi/api
|
||||
,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:None
|
||||
[2018-04-02 10:53:02.390378] INFO: jiekou: 返回结果:{'code': 0, 'result': {'code': 40007, 'text': '您的请求内容为空。'}}
|
||||
[2018-04-02 10:53:02.390378] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2018-04-02 10:53:02.390378] INFO: jiekou: 全部args参数参数信息 , ()
|
||||
[2018-04-02 10:53:02.390378] INFO: jiekou: 全部kwargs参数信息 , {'asserqingwang': 'code=40002'}
|
||||
[2018-04-02 10:53:02.390378] INFO: jiekou: 测试用例执行完毕
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id='ft1.3' class='none'>
|
||||
<td class='text text-warning'>
|
||||
<div class='testcase'>test_api_3</div>
|
||||
</td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();'
|
||||
href="javascript:showTestDetail('div_ft1.3')">
|
||||
error</a>
|
||||
|
||||
<div id='div_ft1.3' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();'
|
||||
onclick="document.getElementById('div_ft1.3').style.display = 'none' ">
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
ft1.3: [2018-04-02 10:53:02.391378] INFO: jiekou: 测试用例开始执行
|
||||
[2018-04-02 10:53:02.391378] INFO: jiekou: 输入参数:url:https://api.douban.com/v2/photo/:id,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:GET
|
||||
[2018-04-02 10:53:02.391378] INFO: jiekou: 输入参数:url:https://api.douban.com/v2/photo/:id,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:None
|
||||
[2018-04-02 10:53:05.242541] INFO: jiekou: 返回结果:{'code': 0, 'result': {'msg': 'uri_not_found', 'code': 1001, 'request': 'GET /v2/photo/:id'}}
|
||||
[2018-04-02 10:53:05.242541] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2018-04-02 10:53:05.243541] INFO: jiekou: 全部args参数参数信息 , ()
|
||||
[2018-04-02 10:53:05.243541] INFO: jiekou: 全部kwargs参数信息 , {'asserqingwang': ''}
|
||||
[2018-04-02 10:53:05.243541] INFO: jiekou: 填写测试预期值
|
||||
[2018-04-02 10:53:05.243541] INFO: jiekou: 测试用例执行完毕
|
||||
Traceback (most recent call last):
|
||||
File "C:\Users\Administrator\AppData\Roaming\Python\Python36\site-packages\ddt.py", line 139, in wrapper
|
||||
return func(self, *args, **kwargs)
|
||||
File "C:\Users\Administrator\Desktop\jiekou-python3\testCase\ddt_case.py", line 24, in test_api
|
||||
qingwang=assertre(asserqingwang=data_test['qiwang'])
|
||||
File "C:\Users\Administrator\Desktop\jiekou-python3\Public\log.py", line 33, in _wrap
|
||||
return function(*args, **kwargs)
|
||||
File "C:\Users\Administrator\Desktop\jiekou-python3\Public\panduan.py", line 27, in assertre
|
||||
raise {"code":1,'result':'填写测试预期值'}
|
||||
TypeError: exceptions must derive from BaseException
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id='total_row'>
|
||||
<td>Total</td>
|
||||
<td>3</td>
|
||||
<td class="text text-success">2</td>
|
||||
<td class="text text-danger">0</td>
|
||||
<td class="text text-warning">1</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div id='ending'> </div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,9 +5,10 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<title>接口测试报告</title>
|
||||
<title>报告</title>
|
||||
<meta name="generator" content="BSTestRunner 0.8.4"/>
|
||||
<link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/3.3.0/css/bootstrap.min.css">
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
||||
|
||||
<style type="text/css" media="screen">
|
||||
|
||||
@@ -49,15 +50,145 @@
|
||||
<!--[if lt IE 9]>
|
||||
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
|
||||
<script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<script language="javascript" type="text/javascript"><!--
|
||||
<div class="container">
|
||||
|
||||
<div class='heading'>
|
||||
<div style='width: 50%;float:left;margin-top:inherit'>
|
||||
<h1>报告</h1>
|
||||
<p><strong>开始时间:</strong> 2022-01-15 14:27:09</p>
|
||||
<p><strong>持续时间:</strong> 0:00:00.003047</p>
|
||||
<p><strong>状态:</strong> <span class="text text-success">通过 <strong>2</strong></span></p>
|
||||
|
||||
<p class='description'>测试报告</p>
|
||||
</div>
|
||||
|
||||
<div id='container2' style='width:50%;float:left;margin-top:20px;height:200px;'>
|
||||
</div>
|
||||
</div >
|
||||
<div id='containerchart' style='height: 300px;margin-top: 20%;'></div>
|
||||
|
||||
|
||||
<p id='show_detail_line'>
|
||||
<span class="label label-primary" onclick="showCase(0)">公用</span>
|
||||
<span class="label label-danger" onclick="showCase(1)">失败</span>
|
||||
<span class="label label-default" onclick="showCase(2)">所有</span>
|
||||
</p>
|
||||
<table id='result_table' class="table">
|
||||
<thead>
|
||||
<tr id='header_row'>
|
||||
<th>测试组/测试用例</td>
|
||||
<th>数量</td>
|
||||
<th>失败</td>
|
||||
<th>通过</td>
|
||||
<th>错误</td>
|
||||
<th>查看</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr class='text text-success'>
|
||||
<td>testCase.ddt_case.MyTest</td>
|
||||
<td>2</td>
|
||||
<td>2</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td><a class="btn btn-xs btn-primary"href="javascript:showClassDetail('c1',2)">详情</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.1' class='hiddenRow'>
|
||||
<td class='text text-success'><div class='testcase'>test_api_1</div></td>
|
||||
<td colspan='5' align='center'>通过</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.2' class='hiddenRow'>
|
||||
<td class='text text-success'><div class='testcase'>test_api_2</div></td>
|
||||
<td colspan='5' align='center'>通过</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id='total_row'>
|
||||
<td>总计</td>
|
||||
<td>2</td>
|
||||
<td class="text text-success">2</td>
|
||||
<td class="text text-danger">0</td>
|
||||
<td class="text text-warning">0</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div id='ending'> </div>
|
||||
</div>
|
||||
|
||||
<script language='javascript' type='text/javascript'>
|
||||
var dom = document.getElementById('containerchart');
|
||||
var myChart = echarts.init(dom);
|
||||
var domone = document.getElementById('container2');
|
||||
var myChartone = echarts.init(domone);
|
||||
var optionsone;
|
||||
optionsone = {
|
||||
title: {
|
||||
text: '历史记录'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: ['成功', '失败','错误']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: ['2022_01_15_14_26_57', '2022_01_15_14_26_21', '2022_01_15_14_27_09']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '成功',
|
||||
type: 'line',
|
||||
stack: '总量',
|
||||
data: ['2', '2', '2']
|
||||
},
|
||||
{
|
||||
name: '失败',
|
||||
type: 'line',
|
||||
stack: '总量',
|
||||
data: ['0', '0', '0']
|
||||
},
|
||||
{
|
||||
name: '错误',
|
||||
type: 'line',
|
||||
stack: '总量',
|
||||
data: ['0', '0', '0']
|
||||
}
|
||||
|
||||
]
|
||||
};
|
||||
if (optionsone && typeof optionsone === 'object') {
|
||||
myChartone.setOption(optionsone);
|
||||
}
|
||||
output_list = Array();
|
||||
|
||||
/* level - 0:Summary; 1:Failed; 2:All */
|
||||
function showCase(level) {
|
||||
trs = document.getElementsByTagName("tr");
|
||||
trs = document.getElementsByTagName('tr');
|
||||
for (var i = 0; i < trs.length; i++) {
|
||||
tr = trs[i];
|
||||
id = tr.id;
|
||||
@@ -113,7 +244,6 @@ function showClassDetail(cid, count) {
|
||||
function showTestDetail(div_id){
|
||||
var details_div = document.getElementById(div_id)
|
||||
var displayState = details_div.style.display
|
||||
// alert(displayState)
|
||||
if (displayState != 'block' ) {
|
||||
displayState = 'block'
|
||||
details_div.style.display = 'block'
|
||||
@@ -122,149 +252,13 @@ function showTestDetail(div_id){
|
||||
details_div.style.display = 'none'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function html_escape(s) {
|
||||
s = s.replace(/&/g,'&');
|
||||
s = s.replace(/</g,'<');
|
||||
s = s.replace(/>/g,'>');
|
||||
return s;
|
||||
}
|
||||
|
||||
/* obsoleted by detail in <div>
|
||||
function showOutput(id, name) {
|
||||
var w = window.open("", //url
|
||||
name,
|
||||
"resizable,scrollbars,status,width=800,height=450");
|
||||
d = w.document;
|
||||
d.write("<pre>");
|
||||
d.write(html_escape(output_list[id]));
|
||||
d.write("\n");
|
||||
d.write("<a href='javascript:window.close()'>close</a>\n");
|
||||
d.write("</pre>\n");
|
||||
d.close();
|
||||
}
|
||||
*/
|
||||
--></script>
|
||||
|
||||
<div class="container">
|
||||
<div class='heading'>
|
||||
<h1>接口测试报告</h1>
|
||||
<p><strong>Start Time:</strong> 2022-01-15 13:41:51</p>
|
||||
<p><strong>Duration:</strong> 0:00:00.003556</p>
|
||||
<p><strong>Status:</strong> <span class="text text-success">Pass <strong>2</strong></span></p>
|
||||
|
||||
<p class='description'>测试结果</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<p id='show_detail_line'>
|
||||
<span class="label label-primary" onclick="showCase(0)">Summary</span>
|
||||
<span class="label label-danger" onclick="showCase(1)">Failed</span>
|
||||
<span class="label label-default" onclick="showCase(2)">All</span>
|
||||
</p>
|
||||
<table id='result_table' class="table">
|
||||
<thead>
|
||||
<tr id='header_row'>
|
||||
<th>Test Group/Test case</td>
|
||||
<th>Count</td>
|
||||
<th>Pass</td>
|
||||
<th>Fail</td>
|
||||
<th>Error</td>
|
||||
<th>View</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr class='text text-success'>
|
||||
<td>testCase.ddt_case.MyTest</td>
|
||||
<td>2</td>
|
||||
<td>2</td>
|
||||
<td>0</td>
|
||||
<td>0</td>
|
||||
<td><a class="btn btn-xs btn-primary"href="javascript:showClassDetail('c1',2)">Detail</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.1' class='hiddenRow'>
|
||||
<td class='text text-success'><div class='testcase'>test_api_1</div></td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.1')" >
|
||||
pass</a>
|
||||
|
||||
<div id='div_pt1.1' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();' onclick="document.getElementById('div_pt1.1').style.display = 'none' " >
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
pt1.1: [2022-01-15 13:41:51.307929] INFO: jiekou: 测试用例开始执行
|
||||
[2022-01-15 13:41:51.308125] INFO: jiekou: 输入参数:url:/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:POST
|
||||
[2022-01-15 13:41:51.308411] INFO: jiekou: 输入参数:url:/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:None
|
||||
[2022-01-15 13:41:51.309817] INFO: jiekou: 返回结果:{'code': 1, 'result': "请求异常:Invalid URL '/openapi/api': No schema supplied. Perhaps you meant http:///openapi/api?"}
|
||||
[2022-01-15 13:41:51.309979] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2022-01-15 13:41:51.310077] INFO: jiekou: 全部args参数参数信息 , ()
|
||||
[2022-01-15 13:41:51.310160] INFO: jiekou: 全部kwargs参数信息 , {'asserqingwang': 'code=40001'}
|
||||
[2022-01-15 13:41:51.310261] INFO: jiekou: 测试用例执行完毕
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1.2' class='hiddenRow'>
|
||||
<td class='text text-success'><div class='testcase'>test_api_2</div></td>
|
||||
<td colspan='5' align='center'>
|
||||
|
||||
<!--css div popup start-->
|
||||
<a class="popup_link btn btn-xs btn-default" onfocus='this.blur();' href="javascript:showTestDetail('div_pt1.2')" >
|
||||
pass</a>
|
||||
|
||||
<div id='div_pt1.2' class="popup_window">
|
||||
<div style='text-align: right;cursor:pointer'>
|
||||
<a onfocus='this.blur();' onclick="document.getElementById('div_pt1.2').style.display = 'none' " >
|
||||
[x]</a>
|
||||
</div>
|
||||
<pre>
|
||||
|
||||
pt1.2: [2022-01-15 13:41:51.310391] INFO: jiekou: 测试用例开始执行
|
||||
[2022-01-15 13:41:51.310482] INFO: jiekou: 输入参数:url:/openapi/api,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:POST
|
||||
[2022-01-15 13:41:51.310559] INFO: jiekou: 输入参数:url:/openapi/api,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:None
|
||||
[2022-01-15 13:41:51.310906] INFO: jiekou: 返回结果:{'code': 1, 'result': "请求异常:Invalid URL '/openapi/api': No schema supplied. Perhaps you meant http:///openapi/api?"}
|
||||
[2022-01-15 13:41:51.311002] INFO: jiekou: 当前模块 断言测试结果
|
||||
[2022-01-15 13:41:51.311085] INFO: jiekou: 全部args参数参数信息 , ()
|
||||
[2022-01-15 13:41:51.311161] INFO: jiekou: 全部kwargs参数信息 , {'asserqingwang': 'code=40002'}
|
||||
[2022-01-15 13:41:51.311249] INFO: jiekou: 测试用例执行完毕
|
||||
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
<!--css div popup end-->
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr id='total_row'>
|
||||
<td>Total</td>
|
||||
<td>2</td>
|
||||
<td class="text text-success">2</td>
|
||||
<td class="text text-danger">0</td>
|
||||
<td class="text text-warning">0</td>
|
||||
<td> </td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<div id='ending'> </div>
|
||||
</div>
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user