At July 22 A.
This commit is contained in:
parent
85e265e5c1
commit
62e91c8647
|
@ -0,0 +1,59 @@
|
|||
import logging
|
||||
|
||||
|
||||
class Logger:
|
||||
logger = None
|
||||
levels = {
|
||||
"CRITICAL": logging.CRITICAL, "FATAL": logging.FATAL, "ERROR": logging.ERROR, "WARNING": logging.WARNING,
|
||||
"WARN": logging.WARN, "INFO": logging.INFO, "DEBUG": logging.DEBUG, "NOTSET": logging.NOTSET,
|
||||
"D": logging.DEBUG, "I": logging.INFO, "W": logging.WARNING, "E": logging.ERROR,
|
||||
"F": logging.FATAL
|
||||
}
|
||||
|
||||
def __init__(self, name: str = '', level='DEBUG', fh: dict = None, ch: dict = None):
|
||||
if fh and (not "format_style" in fh.keys()) and (not '%' in fh["format"]):
|
||||
fh["format_style"] = '{'
|
||||
if ch and (not "format_style" in ch.keys()) and (not '%' in ch["format"]):
|
||||
ch["format_style"] = '{'
|
||||
self.logger = logging.getLogger(name)
|
||||
self.logger.setLevel(self.levels[level])
|
||||
|
||||
if fh:
|
||||
fhandler = logging.FileHandler(filename=fh["filename"], mode=fh["mode"], encoding='utf-8')
|
||||
fhandler.setLevel(self.levels[fh["level"]])
|
||||
fhandler.setFormatter(
|
||||
logging.Formatter(fmt=fh["format"], style=['%', fh["format_style"]]["format_style" in fh.keys()]))
|
||||
self.logger.addHandler(fhandler)
|
||||
if ch:
|
||||
chandler = logging.StreamHandler()
|
||||
chandler.setLevel(self.levels[ch["level"]])
|
||||
chandler.setFormatter(
|
||||
logging.Formatter(fmt=ch["format"], style=['%', ch["format_style"]]["format_style" in ch.keys()]))
|
||||
self.logger.addHandler(chandler)
|
||||
|
||||
self.d = self.logger.debug
|
||||
self.i = self.logger.info
|
||||
self.w = self.logger.warning
|
||||
self.e = self.logger.error
|
||||
self.f = self.logger.fatal
|
||||
self.c = self.logger.critical
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
log = Logger(name='test', level='DEBUG',
|
||||
fh=None and {
|
||||
"level": 'DEBUG',
|
||||
"format": '{asctime} - {name} - {levelname[0]}: {message}',
|
||||
"filename": './test.log',
|
||||
"mode": 'a'
|
||||
},
|
||||
ch={
|
||||
"level": 'DEBUG',
|
||||
"format": '{asctime} - {name} - {levelname[0]}: {message}'
|
||||
})
|
||||
log.d("调试")
|
||||
log.i("信息")
|
||||
log.w("警告")
|
||||
log.e("错误")
|
||||
log.f("致命")
|
||||
log.c("致命")
|
|
@ -1,15 +1,17 @@
|
|||
import time
|
||||
|
||||
|
||||
def time_format(fmt='%Y-%m-%d %H:%M:%S', ts=None):
|
||||
return time.strftime(fmt, time.localtime(ts))
|
||||
def time_strftime(fmt='%Y-%m-%d %H:%M:%S', ts=None, utc=False):
|
||||
return time.strftime(fmt, [time.localtime, time.gmtime][utc](ts))
|
||||
|
||||
|
||||
def time_make(datetime_format='', dt=''):
|
||||
def time_strptime(datetime_format='', dt=''):
|
||||
return time.mktime(time.strptime(dt, datetime_format))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Example.
|
||||
print(time_format(fmt='%Y年%m月%d日 %H:%M:%S'))
|
||||
print(time_format(fmt='%Y年%m月%d日 %H:%M:%S', ts=1640012345))
|
||||
print(time_make('%Y-%m-%d %H:%M:%S', '2021-12-20 22:59:05'))
|
||||
print(time_strftime(fmt='%Y年%m月%d日 %H:%M:%S'))
|
||||
print(time_strftime(fmt='%Y年%m月%d日 %H:%M:%S', ts=1640012345))
|
||||
print(time_strftime(fmt='%H:%M:%S', ts=120, utc=True))
|
||||
print(time_strptime('%Y-%m-%d %H:%M:%S', '2021-12-20 22:59:05'))
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
A TestRunner for use with the Python unit testing framework. It
|
||||
generates a HTML report to show the result at a glance.
|
||||
|
@ -63,123 +62,12 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
|
||||
# URL: http://tungwaiyip.info/software/HTMLTestRunner.html
|
||||
# URL: https://github.com/Gelomen/HTMLTestReportCN-ScreenShot
|
||||
|
||||
__author__ = "Wai Yip Tung, Findyou, boafantasy, Gelomen"
|
||||
__version__ = "1.2.0"
|
||||
|
||||
"""
|
||||
Change History
|
||||
Version 1.3.0 -- Gelomen
|
||||
* 增加初始化报告目录自定义
|
||||
* 升级版本
|
||||
* 优化命名
|
||||
|
||||
Version 1.2.0 -- Gelomen
|
||||
* 优化用例说明显示
|
||||
* 错误和失败报告里可以放入多张截图
|
||||
|
||||
Version 1.1.0 -- Gelomen
|
||||
* 优化报告截图写入方式
|
||||
|
||||
Version 1.0.2 -- Gelomen
|
||||
* 新增测试结果统计饼图
|
||||
* 优化筛选时只显示预览
|
||||
|
||||
Version 1.0.1 -- Gelomen
|
||||
* 修复报告存入文件夹的bug
|
||||
* 优化报告的命名方式
|
||||
|
||||
Version 1.0.0 -- Gelomen
|
||||
* 修改测试报告文件夹路径的获取方式
|
||||
* 修改截图获取文件夹路径的获取方式
|
||||
|
||||
Version 0.9.9 -- Gelomen
|
||||
* 优化报告文件夹命名
|
||||
* 优化截图存放的目录
|
||||
* 增加图片阴影边框以突出图片
|
||||
* 优化 失败用例合集 和 错误用例合集 显示的颜色
|
||||
|
||||
Version 0.9.8 -- Gelomen
|
||||
* 优化回到顶部按钮的显示方式
|
||||
|
||||
Version 0.9.7 -- Gelomen
|
||||
* 优化截图显示,滚动页面会固定居中
|
||||
|
||||
Version 0.9.6 -- Gelomen
|
||||
* 新增打开图片的特效,可以直接在当前页面看截图
|
||||
|
||||
Version 0.9.5 -- Gelomen
|
||||
* heading新增 失败 和 错误 测试用例合集
|
||||
|
||||
Version 0.9.4 -- Gelomen
|
||||
* 修复失败和错误用例里对应按钮的颜色
|
||||
|
||||
Version 0.9.3 -- Gelomen
|
||||
* 修复点击失败或错误按钮后,浏览器版本和截图的列不会隐藏的bug
|
||||
|
||||
Version 0.9.2 -- Gelomen
|
||||
* 美化 浏览器版本 和 截图 的显示
|
||||
|
||||
Version 0.9.1 -- Gelomen
|
||||
* 使用UI自动化测试时,增加 错误、失败 详细信息的 浏览器类型和版本
|
||||
|
||||
Version 0.9.0 -- Gelomen
|
||||
* 可通过 `need_screenshot=1` 作为开关,将报告开启截图功能
|
||||
* 增加 失败 和 错误 详细信息的 截图链接
|
||||
|
||||
Version 0.8.4 -- Gelomen
|
||||
* 删除 失败模块 的显示
|
||||
|
||||
Version 0.8.3 -- Gelomen
|
||||
* 修复 测试结果 的筛选
|
||||
* 优化 失败、错误 小图标的颜色
|
||||
* 增加表格 最后一列 的显示,以美化表格
|
||||
|
||||
Version 0.8.2.1 -Findyou
|
||||
* 改为支持python3
|
||||
|
||||
Version 0.8.2.1 -Findyou
|
||||
* 支持中文,汉化
|
||||
* 调整样式,美化(需要连入网络,使用的百度的Bootstrap.js)
|
||||
* 增加 通过分类显示、测试人员、通过率的展示
|
||||
* 优化“详细”与“收起”状态的变换
|
||||
* 增加返回顶部的锚点
|
||||
|
||||
Version 0.8.2
|
||||
* Show output inline instead of popup window (Viorel Lupu).
|
||||
|
||||
Version in 0.8.1
|
||||
* Validated XHTML (Wolfgang Borgert).
|
||||
* Added description of test classes and test cases.
|
||||
|
||||
Version in 0.8.0
|
||||
* Define Template_mixin class for customization.
|
||||
* Workaround a IE 6 bug that it does not treat <script> block as CDATA.
|
||||
|
||||
Version in 0.7.1
|
||||
* Back port to Python 2.3 (Frank Horowitz).
|
||||
* Fix missing scroll bars in detail log (Podi).
|
||||
"""
|
||||
|
||||
# TODO: color stderr
|
||||
# TODO: simplify javascript using ,ore than 1 class in the class attribute?
|
||||
|
||||
import datetime
|
||||
import io
|
||||
import time
|
||||
import unittest
|
||||
import os, re, sys, io, time, datetime, unittest, logging
|
||||
from xml.sax import saxutils
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
# 全局变量 -- Gelomen
|
||||
_global_dict = {}
|
||||
|
||||
|
||||
# 让新建的报告文件夹路径存入全局变量 -- Gelomen
|
||||
class GlobalMsg(object):
|
||||
def __init__(self):
|
||||
global _global_dict
|
||||
|
@ -281,18 +169,18 @@ class Template_mixin(object):
|
|||
|
||||
DEFAULT_TITLE = '测试报告'
|
||||
DEFAULT_DESCRIPTION = ''
|
||||
DEFAULT_TESTER = 'QA'
|
||||
DEFAULT_TESTER = 'Tester'
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# HTML Template
|
||||
|
||||
HTML_TMPL = r"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
# 网页模板开始
|
||||
# 网页模板,变量列表 title, generator, stylesheet, heading, report, ending
|
||||
HTML_TMPL = r"""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>%(title)s</title>
|
||||
<meta name="generator" content="%(generator)s"/>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0"/>
|
||||
<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>
|
||||
|
@ -311,6 +199,8 @@ class Template_mixin(object):
|
|||
$(this).addClass("btn-danger")
|
||||
}else if(text == "错误") {
|
||||
$(this).addClass("btn-warning")
|
||||
}else if(text == "通过") {
|
||||
$(this).addClass("btn-success")
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -356,10 +246,16 @@ class Template_mixin(object):
|
|||
// 改变窗口大小时,自动改变饼图的边距 -- Gelomen
|
||||
var browserWidth = $(window).width();
|
||||
var margin_left = browserWidth/2 - 450;
|
||||
if(margin_left <= 240){
|
||||
if(margin_left <= 0){
|
||||
$("#container").css("margin", "auto");
|
||||
$("#container").css("float", "left");
|
||||
$("#container").css("width", "100%%");
|
||||
$("#testinfo").css("width", "100%%");
|
||||
}else {
|
||||
$("#container").css("margin-left", margin_left + "px");
|
||||
$("#container").css("float", "right");
|
||||
$("#container").css("width", "450px");
|
||||
$("#testinfo").css("width", "30%%");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -378,7 +274,6 @@ class Template_mixin(object):
|
|||
$("#toTop").click(function() {
|
||||
$("html,body").animate({"scrollTop":0}, 700)
|
||||
})
|
||||
|
||||
// 增加饼状图 -- Gelomen
|
||||
$('#container').highcharts({
|
||||
chart: {
|
||||
|
@ -400,7 +295,7 @@ class Template_mixin(object):
|
|||
text: '测试结果占比'
|
||||
},
|
||||
tooltip: {
|
||||
pointFormat: '{series.name}: <b>{point.percentage:.1f}%%</b>'
|
||||
pointFormat: '<text style="font-size:10px">{series.name}: {point.percentage:.1f}%%</text>'
|
||||
},
|
||||
plotOptions: {
|
||||
pie: {
|
||||
|
@ -430,21 +325,15 @@ class Template_mixin(object):
|
|||
innerSize: '80%%',
|
||||
name: '比例',
|
||||
data: [
|
||||
['通过', %(Pass)s],
|
||||
{
|
||||
name: '失败',
|
||||
y: %(fail)s,
|
||||
sliced: true,
|
||||
selected: true
|
||||
},
|
||||
['错误', %(error)s]
|
||||
['通过', %(Pass)s], ['失败', %(fail)s], ['错误', %(error)s]
|
||||
]
|
||||
}]
|
||||
}, function(c) {
|
||||
// 环形图圆心
|
||||
// 环形圆心
|
||||
var centerY = c.series[0].center[1],
|
||||
titleHeight = parseInt(c.title.styles.fontSize);
|
||||
c.setTitle({
|
||||
x:0,
|
||||
y:centerY + titleHeight/2
|
||||
});
|
||||
chart = c;
|
||||
|
@ -482,8 +371,10 @@ function showCase(level) {
|
|||
else {
|
||||
tr.className = '';
|
||||
// 切换筛选时只显示预览 -- Gelomen
|
||||
// 失败
|
||||
$("div[id^='div_ft']").attr("class", "collapse");
|
||||
$("div[id^='div_et']").attr("class", "collapse");
|
||||
$("div[id^='div_pt']").attr("class", "collapse");
|
||||
}
|
||||
}
|
||||
if (id.substr(0,2) == 'pt') {
|
||||
|
@ -493,8 +384,10 @@ function showCase(level) {
|
|||
else {
|
||||
tr.className = '';
|
||||
// 切换筛选时只显示预览 -- Gelomen
|
||||
// 通过
|
||||
$("div[id^='div_ft']").attr("class", "collapse");
|
||||
$("div[id^='div_et']").attr("class", "collapse");
|
||||
$("div[id^='div_pt']").attr("class", "collapse");
|
||||
}
|
||||
}
|
||||
if (id.substr(0,2) == 'et') {
|
||||
|
@ -504,8 +397,10 @@ function showCase(level) {
|
|||
else {
|
||||
tr.className = '';
|
||||
// 切换筛选时只显示预览 -- Gelomen
|
||||
// 错误
|
||||
$("div[id^='div_ft']").attr("class", "collapse");
|
||||
$("div[id^='div_et']").attr("class", "collapse");
|
||||
$("div[id^='div_pt']").attr("class", "collapse");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +408,7 @@ function showCase(level) {
|
|||
//加入【详细】切换文字变化 --Findyou
|
||||
detail_class=document.getElementsByClassName('detail');
|
||||
//console.log(detail_class.length)
|
||||
if (level == 3) {
|
||||
if (level == 4) {
|
||||
for (var i = 0; i < detail_class.length; i++){
|
||||
detail_class[i].innerHTML="收起"
|
||||
}
|
||||
|
@ -570,11 +465,12 @@ function html_escape(s) {
|
|||
%(heading)s
|
||||
%(report)s
|
||||
%(ending)s
|
||||
|
||||
<div style='width:auto;height:24px;line-height:24px;border:1px solid #e3e3e3;text-align:center'><a href='#' style='color:#505050'></a></div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
# variables: (title, generator, stylesheet, heading, report, ending)
|
||||
# 网页模板结束
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Stylesheet
|
||||
|
@ -597,13 +493,13 @@ table { font-size: 100%; }
|
|||
|
||||
/* --- 失败和错误合集样式 -- Gelomen --- */
|
||||
.failCollection, .errorCollection {
|
||||
width: 100px;
|
||||
width: auto;
|
||||
float: left;
|
||||
}
|
||||
#failCaseOl li {
|
||||
#failedCaseOl li {
|
||||
color: red
|
||||
}
|
||||
#errorCaseOl li {
|
||||
#errorsCaseOl li {
|
||||
color: orange
|
||||
}
|
||||
|
||||
|
@ -656,18 +552,19 @@ table { font-size: 100%; }
|
|||
|
||||
/* --- 饼状图div样式 -- Gelomen --- */
|
||||
#container {
|
||||
max-width: 100%;
|
||||
width: 450px;
|
||||
height: 300px;
|
||||
float: left;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* -- report ------------------------------------------------------------------------ */
|
||||
#total_row { font-weight: bold; }
|
||||
.passCase { color: #5cb85c; }
|
||||
.failCase { color: #d9534f; font-weight: bold; }
|
||||
.errorCase { color: #f0ad4e; font-weight: bold; }
|
||||
.passedCase { color: #3FB83F; font-family: Menlo,Monaco,Consolas,"Courier New",monospace; font-size: 14px; font-weight: bold; }
|
||||
.failedCase { color: #D9433F; font-family: Menlo,Monaco,Consolas,"Courier New",monospace; font-size: 14px; font-weight: bold; }
|
||||
.errorsCase { color: #F0A02F; font-family: Menlo,Monaco,Consolas,"Courier New",monospace; font-size: 14px; font-weight: bold; }
|
||||
.hiddenRow { display: none; }
|
||||
.testcase { margin-left: 2em; }
|
||||
.testcase { margin-left: 1em; word-break: break-all; white-space: pre-wrap; }
|
||||
.screenshot:link { text-decoration: none;color: deeppink; }
|
||||
.screenshot:visited { text-decoration: none;color: deeppink; }
|
||||
.screenshot:hover { text-decoration: none;color: darkcyan; }
|
||||
|
@ -676,43 +573,49 @@ table { font-size: 100%; }
|
|||
"""
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Heading
|
||||
#
|
||||
|
||||
# 添加显示截图 和 饼状图 的div -- Gelomen
|
||||
HEADING_TMPL = """<div class='pic_looper'></div> <div class='pic_show'><div class='pic_box'><img src=''/></div> </div>
|
||||
# 头部信息开始
|
||||
# 添加显示截图和统计图div,变量列表 title, parameters, description
|
||||
HEADING_TMPL = """
|
||||
<div class='pic_looper'></div>
|
||||
<div class='pic_show'>
|
||||
<div class='pic_box'>
|
||||
<img src=''/>
|
||||
</div>
|
||||
</div>
|
||||
<div class='heading'>
|
||||
<div style="width: 650px; float: left;">
|
||||
<div id="testinfo" style="max-width:515px ;width: auto; float: left;">
|
||||
<h1 style="font-family: Microsoft YaHei">%(title)s</h1>
|
||||
%(parameters)s
|
||||
<p class='description'>%(description)s</p>
|
||||
</div>
|
||||
<div id="container"></div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
""" # variables: (title, parameters, description)
|
||||
|
||||
HEADING_ATTRIBUTE_TMPL = """<p class='attribute'><strong>%(name)s : </strong> %(value)s</p>
|
||||
""" # variables: (name, value)
|
||||
# 测试信息模板,变量列表 name, value
|
||||
HEADING_ATTRIBUTE_TMPL = """
|
||||
<p class='attribute'><strong>%(name)s : </strong> %(value)s</p>
|
||||
"""
|
||||
# 头部信息结束
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Report
|
||||
#
|
||||
# 汉化,加美化效果 --Findyou
|
||||
# 报告模板开始
|
||||
# 变量列表 test_list, count, Pass, fail, error ,passrate
|
||||
REPORT_TMPL = """
|
||||
<div style="width: 500px; clear: both;">
|
||||
<div style="width: auto; clear: both;">
|
||||
<p id='show_detail_line'>
|
||||
<a class="btn btn-primary" href='javascript:showCase(0)'>概要{ %(passrate)s }</a>
|
||||
<a class="btn btn-success" href='javascript:showCase(2)'>通过{ %(Pass)s }</a>
|
||||
<a class="btn btn-danger" href='javascript:showCase(1)'>失败{ %(fail)s }</a>
|
||||
<a class="btn btn-warning" href='javascript:showCase(3)'>错误{ %(error)s }</a>
|
||||
<a class="btn btn-info" href='javascript:showCase(4)'>所有{ %(count)s }</a>
|
||||
<a class="btn btn-primary" href='javascript:showCase(0)'>概要 %(passrate)s</a>
|
||||
<a class="btn btn-success" href='javascript:showCase(2)'>通过 %(Pass)s</a>
|
||||
<a class="btn btn-danger" href='javascript:showCase(1)'>失败 %(fail)s</a>
|
||||
<a class="btn btn-warning" href='javascript:showCase(3)'>错误 %(error)s</a>
|
||||
<a class="btn btn-info" href='javascript:showCase(4)'>全部 %(count)s</a>
|
||||
</p>
|
||||
</div>
|
||||
<table id='result_table' class="table table-condensed table-bordered table-hover">
|
||||
<colgroup>
|
||||
<col align='left' style="width: 300px;"/>
|
||||
<col align='right' style="width: 300px;"/>
|
||||
<col align='right' style="width: 285px;"/>
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
<col align='right' />
|
||||
|
@ -721,7 +624,7 @@ table { font-size: 100%; }
|
|||
<col align='right' style="width: 200px;"/>
|
||||
</colgroup>
|
||||
<tr id='header_row' class="text-center success" style="font-weight: bold;font-size: 14px;">
|
||||
<td>用例集/测试用例</td>
|
||||
<td>测试用例</td>
|
||||
<td>说明</td>
|
||||
<td>总计</td>
|
||||
<td>通过</td>
|
||||
|
@ -738,12 +641,13 @@ table { font-size: 100%; }
|
|||
<td>%(fail)s</td>
|
||||
<td>%(error)s</td>
|
||||
<td>%(time_usage)s</td>
|
||||
<td>通过率:%(passrate)s</td>
|
||||
<td>通过:%(passrate)s</td>
|
||||
</tr>
|
||||
</table>
|
||||
""" # variables: (test_list, count, Pass, fail, error ,passrate)
|
||||
"""
|
||||
|
||||
REPORT_CLASS_TMPL = r"""
|
||||
# 变量列表 style, desc, count, Pass, fail, error, cid
|
||||
REPORT_CLASS_TMPL = """
|
||||
<tr class='%(style)s warning'>
|
||||
<td>%(name)s</td>
|
||||
<td>%(doc)s</td>
|
||||
|
@ -752,80 +656,67 @@ table { font-size: 100%; }
|
|||
<td class="text-center">%(fail)s</td>
|
||||
<td class="text-center">%(error)s</td>
|
||||
<td class="text-center">%(time_usage)s</td>
|
||||
<td class="text-center"><a href="javascript:showClassDetail('%(cid)s',%(count)s)" class="detail" id='%(cid)s'>详细</a></td>
|
||||
<td class="text-center"><a href="javascript:showClassDetail('%(cid)s',%(count)s)" class="detail" id='%(cid)s'>查看全部</a></td>
|
||||
</tr>
|
||||
""" # variables: (style, desc, count, Pass, fail, error, cid)
|
||||
"""
|
||||
|
||||
# 失败 的样式,去掉原来JS效果,美化展示效果 -Findyou / 美化类名上下居中,有截图列 -- Gelomen
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL_1 = r"""
|
||||
# 失败样式(有截图列),变量列表 tid, Class, style, desc, status
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL_1 = """
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s' style="vertical-align: middle"><div class='testcase'>%(name)s</div></td>
|
||||
<td style="vertical-align: middle">%(doc)s</td>
|
||||
<td colspan='5' align='center'>
|
||||
<!--默认收起错误信息 -Findyou
|
||||
<button id='btn_%(tid)s' type="button" class="btn btn-xs collapsed" data-toggle="collapse" data-target='#div_%(tid)s'>%(status)s</button>
|
||||
<div id='div_%(tid)s' class="collapse"> -->
|
||||
|
||||
<!-- 默认展开错误信息 -Findyou / 修复失败按钮的颜色 -- Gelomen -->
|
||||
<button id='btn_%(tid)s' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_%(tid)s,#div_%(tid)s_screenshot'>%(status)s</button>
|
||||
<div id='div_%(tid)s' class="collapse in">
|
||||
<pre style="text-align:left">
|
||||
<pre style="text-align:left;font-size:12px;color:#e52000">
|
||||
%(script)s
|
||||
</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center" style="vertical-align: middle"><div id='div_%(tid)s_screenshot' class="collapse in">浏览器版本:<div style="color: brown;">%(browser)s</div></br>截图:%(screenshot)s</div></td>
|
||||
<td class="text-center" style="vertical-align: middle"><div id='div_%(tid)s_screenshot' class="collapse in">浏览器:<div style="color: brown;">%(browser)s</div></br>截图:%(screenshot)s</div></td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
"""
|
||||
|
||||
# 失败 的样式,去掉原来JS效果,美化展示效果 -Findyou / 美化类名上下居中,无截图列 -- Gelomen
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL_0 = r"""
|
||||
# 失败样式(无截图列),变量列表 tid, Class, style, desc, status
|
||||
REPORT_TEST_WITH_OUTPUT_TMPL_0 = """
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s' style="vertical-align: middle"><div class='testcase'>%(name)s</div></td>
|
||||
<td style="vertical-align: middle">%(doc)s</td>
|
||||
<td colspan='5' align='center'>
|
||||
<!--默认收起错误信息 -Findyou
|
||||
<button id='btn_%(tid)s' type="button" class="btn btn-xs collapsed" data-toggle="collapse" data-target='#div_%(tid)s'>%(status)s</button>
|
||||
<div id='div_%(tid)s' class="collapse"> -->
|
||||
|
||||
<!-- 默认展开错误信息 -Findyou / 修复失败按钮的颜色 -- Gelomen -->
|
||||
<button id='btn_%(tid)s' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_%(tid)s'>%(status)s</button>
|
||||
<div id='div_%(tid)s' class="collapse in">
|
||||
<pre style="text-align:left">
|
||||
%(script)s
|
||||
</pre>
|
||||
<pre style="text-align:left;font-size:12px;color:#e52000">%(script)s</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td class='%(style)s' style="vertical-align: middle"></td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
"""
|
||||
|
||||
# 通过 的样式,加标签效果 -Findyou / 美化类名上下居中 -- Gelomen
|
||||
REPORT_TEST_NO_OUTPUT_TMPL = r"""
|
||||
# 通过样式,变量列表 tid, Class, style, desc, status
|
||||
REPORT_TEST_NO_OUTPUT_TMPL = """
|
||||
<tr id='%(tid)s' class='%(Class)s'>
|
||||
<td class='%(style)s' style="vertical-align: middle"><div class='testcase'>%(name)s</div></td>
|
||||
<td style="vertical-align: left">%(doc)s</td>
|
||||
<td colspan='5' align='center'><span class="label label-success success">%(status)s</span></td>
|
||||
<td colspan='5' align='center'><button type="button" class="btn btn-xs">%(status)s</button></td>
|
||||
<td class='%(style)s' style="vertical-align: middle"></td>
|
||||
</tr>
|
||||
""" # variables: (tid, Class, style, desc, status)
|
||||
|
||||
REPORT_TEST_OUTPUT_TMPL = r"""
|
||||
%(id)s: %(output)s
|
||||
""" # variables: (id, output)
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# ENDING
|
||||
#
|
||||
# 增加返回顶部按钮 --Findyou
|
||||
ENDING_TMPL = """<div id='ending'> </div>
|
||||
<div id="toTop" style=" position:fixed;right:50px; bottom:30px; width:20px; height:20px;cursor:pointer; display: none">
|
||||
<a><span class="glyphicon glyphicon-eject" style = "font-size:30px;" aria-hidden="true">
|
||||
</span></a></div>
|
||||
"""
|
||||
|
||||
# 测试输出内容
|
||||
REPORT_TEST_OUTPUT_TMPL = '%(id)s:' + "\n" + '%(output)s'
|
||||
|
||||
# -------------------- The end of the Template class -------------------
|
||||
# 返回顶部按钮
|
||||
ENDING_TMPL = """
|
||||
<div id='ending'> </div>
|
||||
<div id="toTop" style="position:fixed;right:50px; bottom:30px; width:20px; height:20px;cursor:pointer; display: none">
|
||||
<a>
|
||||
<span class="glyphicon glyphicon-eject" style = "font-size:28px;color:#b0b0b0" aria-hidden="true">
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
"""
|
||||
# 报告模板结束
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
|
||||
TestResult = unittest.TestResult
|
||||
|
@ -836,13 +727,14 @@ class _TestResult(TestResult):
|
|||
# It lacks the output and reporting ability compares to unittest._TextTestResult.
|
||||
|
||||
def __init__(self, verbosity=1):
|
||||
TestResult.__init__(self)
|
||||
super().__init__(verbosity=verbosity)
|
||||
self.verbosity = verbosity
|
||||
self.outputBuffer = None
|
||||
self.stdout0 = None
|
||||
self.stderr0 = None
|
||||
self.success_count = 0
|
||||
self.failure_count = 0
|
||||
self.error_count = 0
|
||||
self.verbosity = verbosity
|
||||
self.passed_count = 0
|
||||
self.failed_count = 0
|
||||
self.errors_count = 0
|
||||
|
||||
# result is a list of result in 4 tuple
|
||||
# (
|
||||
|
@ -852,13 +744,14 @@ class _TestResult(TestResult):
|
|||
# stack trace,
|
||||
# )
|
||||
self.result = []
|
||||
# 增加一个测试通过率 --Findyou
|
||||
self.passrate = float(0)
|
||||
|
||||
# 增加失败用例合集
|
||||
self.failCase = ""
|
||||
self.failedCase = ""
|
||||
# 增加错误用例合集
|
||||
self.errorCase = ""
|
||||
self.errorsCase = ""
|
||||
|
||||
self.logger = logging.getLogger('test')
|
||||
|
||||
def startTest(self, test):
|
||||
stream = sys.stderr
|
||||
|
@ -866,7 +759,7 @@ class _TestResult(TestResult):
|
|||
# stream.write(stdout_content)
|
||||
# stream.flush()
|
||||
# stream.write("\n")
|
||||
TestResult.startTest(self, test)
|
||||
super().startTest(test)
|
||||
# just one buffer for both stdout and stderr
|
||||
self.outputBuffer = io.StringIO()
|
||||
stdout_redirector.fp = self.outputBuffer
|
||||
|
@ -875,48 +768,57 @@ class _TestResult(TestResult):
|
|||
self.stderr0 = sys.stderr
|
||||
sys.stdout = stdout_redirector
|
||||
sys.stderr = stderr_redirector
|
||||
self.test_start_time = round(time.time(), 2)
|
||||
self.stime = round(time.time(), 2)
|
||||
|
||||
self.loggerStream = io.StringIO()
|
||||
self.ch = logging.StreamHandler(self.loggerStream)
|
||||
self.ch.setLevel(logging.DEBUG)
|
||||
self.ch.setFormatter(
|
||||
logging.Formatter('%(asctime)s - %(name)s -%(levelname)s -%(process)d -%(processName)s - %(message)s'))
|
||||
self.logger.addHandler(self.ch)
|
||||
|
||||
|
||||
def complete_output(self):
|
||||
"""
|
||||
Disconnect output redirection and return buffer.
|
||||
Safe to call multiple times.
|
||||
"""
|
||||
self.test_end_time = round(time.time(), 2)
|
||||
self.etime = round(time.time(), 2)
|
||||
if self.stdout0:
|
||||
sys.stdout = self.stdout0
|
||||
sys.stderr = self.stderr0
|
||||
self.stdout0 = None
|
||||
self.stderr0 = None
|
||||
return self.outputBuffer.getvalue()
|
||||
return self.loggerStream.getvalue() + 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.
|
||||
self.complete_output()
|
||||
# 移除日志Handler
|
||||
self.logger.removeHandler(self.ch)
|
||||
|
||||
def addSuccess(self, test):
|
||||
self.success_count += 1
|
||||
TestResult.addSuccess(self, test)
|
||||
self.passed_count += 1
|
||||
super().addSuccess(test)
|
||||
output = self.complete_output()
|
||||
use_time = round(self.test_end_time - self.test_start_time, 2)
|
||||
self.result.append((0, test, output, '', use_time))
|
||||
utime = round(self.etime - self.stime, 2)
|
||||
self.result.append((0, test, output, '', utime))
|
||||
if self.verbosity > 1:
|
||||
sys.stderr.write(' S ')
|
||||
sys.stderr.write('Passed: ')
|
||||
sys.stderr.write(str(test))
|
||||
sys.stderr.write('\n')
|
||||
else:
|
||||
sys.stderr.write(' S ')
|
||||
sys.stderr.write('\n')
|
||||
sys.stderr.write(str(test.__class__.__doc__))
|
||||
|
||||
|
||||
def addError(self, test, err):
|
||||
self.error_count += 1
|
||||
TestResult.addError(self, test, err)
|
||||
self.errors_count += 1
|
||||
super().addError(test, err)
|
||||
_, _exc_str = self.errors[-1]
|
||||
output = self.complete_output()
|
||||
use_time = round(self.test_end_time - self.test_start_time, 2)
|
||||
self.result.append((2, test, output, _exc_str, use_time))
|
||||
utime = round(self.etime - self.stime, 2)
|
||||
self.result.append((2, test, output, _exc_str, utime))
|
||||
if self.verbosity > 1:
|
||||
sys.stderr.write(' E ')
|
||||
sys.stderr.write(str(test))
|
||||
|
@ -925,16 +827,16 @@ class _TestResult(TestResult):
|
|||
sys.stderr.write(' E ')
|
||||
sys.stderr.write('\n')
|
||||
|
||||
# 添加收集错误用例名字 -- Gelomen
|
||||
self.errorCase += "<li>" + str(test) + "</li>"
|
||||
# 收集错误测试用例名称以在测试报告中显示
|
||||
self.errorsCase += "<li>" + str(test) + "</li>"
|
||||
|
||||
def addFailure(self, test, err):
|
||||
self.failure_count += 1
|
||||
TestResult.addFailure(self, test, err)
|
||||
self.failed_count += 1
|
||||
super().addFailure(test, err)
|
||||
_, _exc_str = self.failures[-1]
|
||||
output = self.complete_output()
|
||||
use_time = round(self.test_end_time - self.test_start_time, 2)
|
||||
self.result.append((1, test, output, _exc_str, use_time))
|
||||
utime = round(self.etime - self.stime, 2)
|
||||
self.result.append((1, test, output, _exc_str, utime))
|
||||
if self.verbosity > 1:
|
||||
sys.stderr.write(' F ')
|
||||
sys.stderr.write(str(test))
|
||||
|
@ -943,8 +845,8 @@ class _TestResult(TestResult):
|
|||
sys.stderr.write(' F ')
|
||||
sys.stderr.write('\n')
|
||||
|
||||
# 添加收集失败用例名字 -- Gelomen
|
||||
self.failCase += "<li>" + str(test) + "</li>"
|
||||
# 收集失败测试用例名称以在测试报告中显示
|
||||
self.failedCase += "<li>" + str(test) + "</li>"
|
||||
|
||||
|
||||
# 新增 need_screenshot 参数,-1为无需截图,否则需要截图 -- Gelomen
|
||||
|
@ -1003,47 +905,47 @@ class HTMLTestRunner(Template_mixin):
|
|||
Override this to add custom attributes.
|
||||
"""
|
||||
startTime = str(self.startTime)[:19]
|
||||
duration = str(self.stopTime - self.startTime)
|
||||
duration = time.strftime('%H:%M:%S', time.gmtime((self.stopTime - self.startTime).seconds))
|
||||
status = []
|
||||
status.append('共 %s' % (result.success_count + result.failure_count + result.error_count))
|
||||
if result.success_count:
|
||||
status.append('通过 %s' % result.success_count)
|
||||
if result.failure_count:
|
||||
status.append('失败 %s' % result.failure_count)
|
||||
if result.error_count:
|
||||
status.append('错误 %s' % result.error_count)
|
||||
status.append('总共 %s' % (result.passed_count + result.failed_count + result.errors_count))
|
||||
if result.passed_count:
|
||||
status.append('通过 %s' % result.passed_count)
|
||||
if result.failed_count:
|
||||
status.append('失败 %s' % result.failed_count)
|
||||
if result.errors_count:
|
||||
status.append('错误 %s' % result.errors_count)
|
||||
if status:
|
||||
status = ','.join(status)
|
||||
if (result.success_count + result.failure_count + result.error_count) > 0:
|
||||
self.passrate = str("%.2f%%" % (float(result.success_count) / float(
|
||||
result.success_count + result.failure_count + result.error_count) * 100))
|
||||
if (result.passed_count + result.failed_count + result.errors_count) > 0:
|
||||
self.passrate = str("%.2f%%" % (float(result.passed_count) / float(
|
||||
result.passed_count + result.failed_count + result.errors_count) * 100))
|
||||
else:
|
||||
self.passrate = "0.00 %"
|
||||
else:
|
||||
status = 'none'
|
||||
|
||||
if len(result.failCase) > 0:
|
||||
failCase = result.failCase
|
||||
if len(result.failedCase) > 0:
|
||||
failedCase = result.failedCase
|
||||
else:
|
||||
failCase = "无"
|
||||
failedCase = "无"
|
||||
|
||||
if len(result.errorCase) > 0:
|
||||
errorCase = result.errorCase
|
||||
if len(result.errorsCase) > 0:
|
||||
errorsCase = result.errorsCase
|
||||
else:
|
||||
errorCase = "无"
|
||||
errorsCase = "无"
|
||||
|
||||
return [
|
||||
('测试人员', self.tester),
|
||||
('开始时间', startTime),
|
||||
('合计耗时', duration),
|
||||
('测试结果', status + ",通过率 = " + self.passrate),
|
||||
('失败用例合集', failCase),
|
||||
('错误用例合集', errorCase),
|
||||
('测试结果', status + ",通过率 " + self.passrate),
|
||||
('失败用例', failedCase),
|
||||
('错误用例', errorsCase),
|
||||
]
|
||||
|
||||
def generateReport(self, test, result):
|
||||
report_attrs = self.getReportAttributes(result)
|
||||
generator = 'HTMLTestRunner %s' % __version__
|
||||
generator = 'HTMLTestRunner'
|
||||
stylesheet = self._generate_stylesheet()
|
||||
# 添加 通过、失败 和 错误 的统计,以用于饼图 -- Gelomen
|
||||
Pass = self._generate_report(result)["Pass"]
|
||||
|
@ -1075,29 +977,29 @@ class HTMLTestRunner(Template_mixin):
|
|||
a_lines = []
|
||||
for name, value in report_attrs:
|
||||
# 如果是 失败用例 或 错误用例合集,则不进行转义 -- Gelomen
|
||||
if name == "失败用例合集":
|
||||
if name == "失败用例":
|
||||
if value == "无":
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name=name,
|
||||
value="<ol style='float: left;'>" + value + "</ol>",
|
||||
value=value,
|
||||
)
|
||||
else:
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name=name,
|
||||
value="<div class='panel-default' style='float: left;'><a class='showDetail' data-toggle='collapse' href='#failCaseOl' style='text-decoration: none;'>点击查看</a></div>"
|
||||
"<ol id='failCaseOl' class='collapse' style='float: left;'>" + value + "</ol>",
|
||||
value="<a class='showDetail' data-toggle='collapse' href='#failedCaseOl' style='text-decoration: none;'>点击查看</a>"
|
||||
"<ol id='failedCaseOl' class='collapse' style='float: left; font-family: Menlo,Monaco,Consolas,monospace;'>" + value + "</ol>",
|
||||
)
|
||||
elif name == "错误用例合集":
|
||||
elif name == "错误用例":
|
||||
if value == "无":
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name=name,
|
||||
value="<ol style='float: left;'>" + value + "</ol>",
|
||||
value=value,
|
||||
)
|
||||
else:
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
name=name,
|
||||
value="<div class='panel-default' style='float: left;'><a class='showDetail' data-toggle='collapse' href='#errorCaseOl' style='text-decoration: none;'>点击查看</a></div>"
|
||||
"<ol id='errorCaseOl' class='collapse' style='float: left;'>" + value + "</ol>",
|
||||
value="<a class='showDetail' data-toggle='collapse' href='#errorsCaseOl' style='text-decoration: none;'>点击查看</a>"
|
||||
"<ol id='errorsCaseOl' class='collapse' style='float: left; font-family: Menlo,Monaco,Consolas,monospace;'>" + value + "</ol>",
|
||||
)
|
||||
else:
|
||||
line = self.HEADING_ATTRIBUTE_TMPL % dict(
|
||||
|
@ -1159,18 +1061,18 @@ class HTMLTestRunner(Template_mixin):
|
|||
sum_ns = round(sum_ns, 2)
|
||||
report = self.REPORT_TMPL % dict(
|
||||
test_list=''.join(rows),
|
||||
count=str(result.success_count + result.failure_count + result.error_count),
|
||||
Pass=str(result.success_count),
|
||||
fail=str(result.failure_count),
|
||||
error=str(result.error_count),
|
||||
count=str(result.passed_count + result.failed_count + result.errors_count),
|
||||
Pass=str(result.passed_count),
|
||||
fail=str(result.failed_count),
|
||||
error=str(result.errors_count),
|
||||
time_usage=str(sum_ns) + "秒", # 所有用例耗时
|
||||
passrate=self.passrate,
|
||||
)
|
||||
|
||||
# 获取 通过、失败 和 错误 的统计并return,以用于饼图 -- Gelomen
|
||||
Pass = str(result.success_count)
|
||||
fail = str(result.failure_count)
|
||||
error = str(result.error_count)
|
||||
Pass = str(result.passed_count)
|
||||
fail = str(result.failed_count)
|
||||
error = str(result.errors_count)
|
||||
return {"report": report, "Pass": Pass, "fail": fail, "error": error}
|
||||
|
||||
def _generate_report_test(self, rows, cid, tid, n, t, o, e):
|
||||
|
@ -1221,7 +1123,7 @@ class HTMLTestRunner(Template_mixin):
|
|||
row = tmpl % dict(
|
||||
tid=tid,
|
||||
Class=(n == 0 and 'hiddenRow' or 'none'),
|
||||
style=n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'passCase'),
|
||||
style=n == 2 and 'errorsCase' or (n == 1 and 'failedCase' or 'passedCase'),
|
||||
name=name,
|
||||
doc=doc,
|
||||
script=script,
|
||||
|
@ -1241,7 +1143,7 @@ class HTMLTestRunner(Template_mixin):
|
|||
row = tmpl % dict(
|
||||
tid=tid,
|
||||
Class=(n == 0 and 'hiddenRow' or 'none'),
|
||||
style=n == 2 and 'errorCase' or (n == 1 and 'failCase' or 'passCase'),
|
||||
style=n == 2 and 'errorsCase' or (n == 1 and 'failedCase' or 'passedCase'),
|
||||
name=name,
|
||||
doc=doc,
|
||||
script=script,
|
||||
|
|
52
run.py
52
run.py
|
@ -4,6 +4,39 @@ from test_case import TestDemo
|
|||
import unittest
|
||||
|
||||
|
||||
from types import FunctionType
|
||||
|
||||
|
||||
|
||||
|
||||
# TestDemo3 = unittest.TestCase
|
||||
# TestDemo3.test_007 = test_007
|
||||
# TestDemo3.test_007.__module__= TestDemo3
|
||||
|
||||
|
||||
obj = type("TestCases",(unittest.TestCase,),dict())
|
||||
obj.__doc__ = 'Doc'
|
||||
obj.test_demo0123456789ABCDEF_000000 = FunctionType(compile('def foo(self): import time; time.sleep(0)', "", "exec").co_consts[0], globals(), "foo")
|
||||
obj.test_demo1 = FunctionType(compile('def foo(self): return "bar"', "", "exec").co_consts[0], globals(), "foo")
|
||||
obj.test_demo2 = FunctionType(compile('def foo(self): assert 1 == 2', "", "exec").co_consts[0], globals(), "foo")
|
||||
obj.test_demo3 = FunctionType(compile('def foo(): return "bar"', "", "exec").co_consts[0], globals(), "foo")
|
||||
obj.test_demo1.__qualname__ = "test_demo1"
|
||||
obj.test_demo1.__doc__ = "这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;"
|
||||
obj.test_demo2.__qualname__ = "test_demo2"
|
||||
obj.test_demo2.__doc__ = "这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;这是一条测试用例;"
|
||||
obj.test_demo3.__qualname__ = "test_demo3"
|
||||
obj.test_demo3.__doc__ = "这是一条测试用例;这是一条测试用例;这是一条测试用例;"
|
||||
# print(obj)
|
||||
|
||||
# foo_code = compile('def foo(): return "bar"', "", "exec")
|
||||
# print(foo_code)
|
||||
# foo_func = FunctionType(foo_code.co_consts[0], globals(), "foo")
|
||||
# foo_func.__qualname__ = "test_demo"
|
||||
# print(foo_func)
|
||||
|
||||
|
||||
|
||||
|
||||
base_path = os.path.dirname(__file__)
|
||||
report_path = base_path
|
||||
report_filename = os.path.join(report_path, 'report.html')
|
||||
|
@ -12,11 +45,28 @@ case_suite = unittest.TestSuite()
|
|||
case_suite.addTest(TestDemo('test_one'))
|
||||
case_suite.addTest(TestDemo('test_two'))
|
||||
case_suite.addTest(TestDemo('test_tre'))
|
||||
case_suite.addTest(TestDemo('test_0123456789ABCDEF_123456_000000'))
|
||||
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo1'))
|
||||
# case_suite.addTest(obj('test_demo2'))
|
||||
# case_suite.addTest(obj('test_demo3'))
|
||||
|
||||
|
||||
def start():
|
||||
with open(report_filename, 'wb') as f:
|
||||
runner = HTMLTestRunner(stream=f, title='自动化测试报告', verbosity=2, description='描述', tester='Tester')
|
||||
runner = HTMLTestRunner(stream=f,
|
||||
title='自动化测试报告',
|
||||
verbosity=2,
|
||||
description='描述',
|
||||
tester='DESKTOP')
|
||||
runner.run(case_suite)
|
||||
|
||||
|
||||
|
|
26
test_case.py
26
test_case.py
|
@ -1,23 +1,33 @@
|
|||
import unittest
|
||||
from Base.Class.Logger import *
|
||||
from Base.Class.Http import *
|
||||
log = Logger(name='test', level='DEBUG', ch={
|
||||
"level": 'DEBUG',
|
||||
"format": '{asctime} - {name} - {levelname[0]}: {message}'
|
||||
})
|
||||
|
||||
|
||||
class TestDemo(unittest.TestCase):
|
||||
def test_one(self):
|
||||
'''
|
||||
哈哈
|
||||
ONE用例
|
||||
:return:
|
||||
'''
|
||||
assert 1 == 1
|
||||
log.i("Info...")
|
||||
log.w("Warnning...")
|
||||
|
||||
def test_two(self):
|
||||
'''
|
||||
呵呵
|
||||
:return:
|
||||
'''
|
||||
assert 'H' in 'Hello!'
|
||||
log.d("正在断言...")
|
||||
assert 'A' in 'Hello!', '断言失败'
|
||||
|
||||
def test_tre(self):
|
||||
assert 5 == 10, '断言失败'
|
||||
assert a == 10
|
||||
|
||||
def test_0123456789ABCDEF_123456_000000(self):
|
||||
Request().http('GET',"http://more-md.fanscloud.net/iplookup", proxy="http://127.0.0.1:8888")
|
||||
pass
|
||||
|
||||
|
||||
TestDemo.test_tre.__doc__ = "测试吖"
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Reference in New Issue