增加依赖用例处理,调整部分代码
This commit is contained in:
@@ -9,19 +9,21 @@ reques = requ()
|
||||
|
||||
|
||||
class TestApi(object):
|
||||
def __init__(self, url, key, connent, fangshi):
|
||||
def __init__(self, url, parame, method):
|
||||
self.url = url
|
||||
self.key = key
|
||||
self.connent = connent
|
||||
self.fangshi = fangshi
|
||||
self.parame = parame
|
||||
self.method = method
|
||||
|
||||
def testapi(self):
|
||||
if self.fangshi == 'POST':
|
||||
self.parem = {'key': self.key, 'info': self.connent}
|
||||
self.response = reques.post(self.url, self.parem)
|
||||
elif self.fangshi == "GET":
|
||||
self.parem = {'key': self.key, 'info': self.connent}
|
||||
self.response = reques.get(url=self.url, params=self.parem)
|
||||
if self.method == 'POST':
|
||||
self.response = reques.post(self.url, self.parame)
|
||||
elif self.method == "GET":
|
||||
self.response = reques.get(url=self.url, params=self.parame)
|
||||
elif self.method == "PUT":
|
||||
self.response = reques.putparams(url=self.url, params=self.parame)
|
||||
elif self.method == "DELETE":
|
||||
self.response = reques.delparams(url=self.url, params=self.parame)
|
||||
|
||||
return self.response
|
||||
|
||||
def getJson(self):
|
||||
|
||||
@@ -99,6 +99,7 @@ import os
|
||||
import sys, copy
|
||||
from io import StringIO as StringIO
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# The redirectors below are used to capture output during testing. Output
|
||||
# sent to sys.stdout and sys.stderr are automatically captured. However
|
||||
@@ -278,7 +279,7 @@ class Template_mixin(object):
|
||||
<p class='description'>%(description)s</p>
|
||||
</div> </div >
|
||||
"""
|
||||
HEADING_TMPL_New="""
|
||||
HEADING_TMPL_New = """
|
||||
<div class='heading'>
|
||||
<div style='width: 50%%;float:left;margin-top:inherit'>
|
||||
<h1>%(title)s</h1>
|
||||
@@ -388,7 +389,7 @@ class Template_mixin(object):
|
||||
#
|
||||
|
||||
ENDING_TMPL = """<div id='ending'> </div>"""
|
||||
SCRPICTold="""
|
||||
SCRPICTold = """
|
||||
<script language='javascript' type='text/javascript'>
|
||||
output_list = Array();
|
||||
|
||||
@@ -468,8 +469,7 @@ function html_escape(s) {
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
SCRPICTDATA=r"""
|
||||
SCRPICTDATA = r"""
|
||||
<script language='javascript' type='text/javascript'>
|
||||
var dom = document.getElementById('containerchart');
|
||||
var myChart = echarts.init(dom);
|
||||
@@ -608,10 +608,14 @@ function html_escape(s) {
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
|
||||
# -------------------- The end of the Template class -------------------
|
||||
|
||||
|
||||
TestResult = unittest.TestResult
|
||||
|
||||
|
||||
class MyResult(TestResult):
|
||||
def __init__(self, verbosity=1, trynum=1):
|
||||
# 默认次数是0
|
||||
@@ -714,7 +718,6 @@ class MyResult(TestResult):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
class _TestResult(MyResult):
|
||||
# note: _TestResult is a pure representation of results.
|
||||
# It lacks the output and reporting ability compares to unittest._TextTestResult.
|
||||
@@ -738,8 +741,8 @@ class BSTestRunner(Template_mixin):
|
||||
self.stream = stream
|
||||
self.verbosity = verbosity
|
||||
self.trynum = trynum
|
||||
self.is_show=is_show
|
||||
self.filepath=filepath
|
||||
self.is_show = is_show
|
||||
self.filepath = filepath
|
||||
if title is None:
|
||||
self.title = self.DEFAULT_TITLE
|
||||
else:
|
||||
@@ -760,9 +763,10 @@ class BSTestRunner(Template_mixin):
|
||||
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__())
|
||||
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))
|
||||
@@ -814,9 +818,9 @@ class BSTestRunner(Template_mixin):
|
||||
report = self._generate_report(result)
|
||||
ending = self._generate_ending()
|
||||
if self.is_show:
|
||||
scrpit=self.___generate_scrpitone()
|
||||
scrpit = self.___generate_scrpitone()
|
||||
else:
|
||||
scrpit=self._generate_scrpit()
|
||||
scrpit = self._generate_scrpit()
|
||||
output = self.HTML_TMPL % dict(
|
||||
title=saxutils.escape(self.title),
|
||||
generator=generator,
|
||||
@@ -832,7 +836,7 @@ class BSTestRunner(Template_mixin):
|
||||
return self.STYLESHEET_TMPL
|
||||
|
||||
def _generate_heading(self, report_attrs):
|
||||
ISSHOWPERDATA=True
|
||||
ISSHOWPERDATA = True
|
||||
if ISSHOWPERDATA:
|
||||
a_lines = []
|
||||
for name, value in report_attrs:
|
||||
@@ -845,7 +849,8 @@ class BSTestRunner(Template_mixin):
|
||||
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),)
|
||||
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),
|
||||
@@ -959,27 +964,30 @@ 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):
|
||||
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("_")
|
||||
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
|
||||
return namerun, faillist, success, error
|
||||
|
||||
def _generate_scrpit(self):
|
||||
return self.SCRPICTold
|
||||
|
||||
@@ -1011,5 +1019,3 @@ main = TestProgram
|
||||
##############################################################################
|
||||
# Executing this module from the command line
|
||||
##############################################################################
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"""
|
||||
'''封装钉钉群发消息'''
|
||||
import requests, json
|
||||
from config.config_T import Dingtalk_access_token
|
||||
from config.config import Dingtalk_access_token
|
||||
|
||||
|
||||
def send_ding(content):
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
# @Author : leizi
|
||||
import smtplib, time, os
|
||||
from email.mime.text import MIMEText
|
||||
from email.utils import formataddr, parseaddr
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.base import MIMEBase
|
||||
import yaml
|
||||
|
||||
|
||||
def load_emil_setting(): # 从配置文件中加载获取email的相关信息
|
||||
import yaml
|
||||
data_file = open(r".\\config\\email.yaml", "r")
|
||||
datas = yaml.load(data_file)
|
||||
filepath = os.path.join(os.path.join(os.getcwd(), 'config'), 'email.yaml')
|
||||
|
||||
data_file = open(filepath, "r")
|
||||
datas = yaml.load(data_file, Loader=yaml.FullLoader)
|
||||
data_file.close()
|
||||
return (datas['foremail'], datas['password'], datas['toeamil'], datas['title'])
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# @Time : 2017/6/4 20:35
|
||||
# @Author : lileilei
|
||||
# @File : get_excel.py
|
||||
import xlrd,os
|
||||
import xlrd, os
|
||||
from Public.log import LOG, logger
|
||||
|
||||
|
||||
@@ -33,13 +33,19 @@ def datacel(filepath):
|
||||
print(e)
|
||||
LOG.info('打开测试用例失败,原因是:%s' % e)
|
||||
return
|
||||
|
||||
|
||||
@logger('生成数据驱动所用数据')
|
||||
def makedata():
|
||||
path = os.path.join(os.path.join(os.getcwd(),'test_case_data'),'case.xlsx')
|
||||
listid, listkey, listconeent, listurl, listfangshi, listqiwang, listname=datacel(path)
|
||||
i=0
|
||||
make_data=[]
|
||||
path = os.path.join(os.path.join(os.getcwd(), 'test_case_data'), 'case.xlsx')
|
||||
listid, listkey, listconeent, listurl, listfangshi, listqiwang, listname = datacel(path)
|
||||
|
||||
make_data = []
|
||||
for i in range(len(listid)):
|
||||
make_data.append({'url':listurl[i],'key':listkey[i],'coneent':listconeent[i],'fangshi':listfangshi[i],'qiwang':listqiwang[i]})
|
||||
i+=1
|
||||
make_data.append({'url': listurl[i], 'key': listkey[i],
|
||||
'coneent': listconeent[i], 'fangshi': listfangshi[i],
|
||||
'qiwang': listqiwang[i],
|
||||
'id': listid[i]},
|
||||
)
|
||||
i += 1
|
||||
return make_data
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
@file: py_Html.py
|
||||
@time: 2017/6/5 17:04
|
||||
"""
|
||||
import os
|
||||
|
||||
titles = '接口测试'
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
@file: pyreport_excel.py
|
||||
@time: 2017/6/7 8:47
|
||||
"""
|
||||
import xlrd, os, xlwt, yaml, xlsxwriter # 导入库
|
||||
import os, xlwt, yaml
|
||||
from xlwt import *
|
||||
|
||||
|
||||
@@ -56,9 +56,8 @@ def yangshique(me):
|
||||
|
||||
def create(filename, list_pass, list_fail, listids, listnames, listkeys, listconeents, listurls, listfangshis,
|
||||
listqiwangs, list_json, listrelust):
|
||||
|
||||
filepath = open( os.path.join(os.path.join(os.getcwd(),'config'),'test_report.yaml'), encoding='utf-8')
|
||||
file_config = yaml.load(filepath,Loader=yaml.FullLoader)
|
||||
filepath = open(os.path.join(os.path.join(os.getcwd(), 'config'), 'test_report.yaml'), encoding='utf-8')
|
||||
file_config = yaml.load(filepath, Loader=yaml.FullLoader)
|
||||
file = Workbook(filename)
|
||||
table = file.add_sheet('测试结果', cell_overwrite_ok=True)
|
||||
style = yangshi1()
|
||||
|
||||
@@ -1 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
@@ -1,5 +1,8 @@
|
||||
# 接口测试框架(基于json格式、http请求,python3,不兼容python2.x版本)
|
||||
## 注:现在基于Excel文件管理测试用例基本实现,)
|
||||
## 备注:大家在运行的时候,如果参数不需要key,只需要字典,可以在ddt_case.py和case.py改造parame,注释掉现在的parem,启用新的即可
|
||||
## 依赖用例支持用例执行,在testCase的ddt_case.py有实现,逻辑在代码中有写,参数的格式{"name":"$case1=data"}即代表name的值是case1的data字段,简单的实现。
|
||||
## 依赖用例是简单的实现,具体在业务上面还有很多复杂的要处理,知识实现了,部分的思路。
|
||||
## (目前在部分window上会出现FileNotFoundError [Errno 2] No such file or directory,这个bug是路径过长,解决方案为吧log日志放在当前目录,或者修改动态生成的文件的名字,给了第一种方式,测试日志放在当前目录)
|
||||
## qq交流群:194704520
|
||||
### 使用的库 requests,绝大部分是基于Python原有的库进行的,这样简单方便,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""
|
||||
@author: lileilei
|
||||
@file: config_T.py
|
||||
@file: config.py
|
||||
@time: 2018/4/12 14:17
|
||||
"""
|
||||
Dingtalk_access_token = "" # 钉钉配置
|
||||
@@ -11,11 +11,11 @@ import threading
|
||||
def stast():
|
||||
starttime = datetime.datetime.now()
|
||||
day = time.strftime("%Y%m%d%H%M", time.localtime(time.time()))
|
||||
path=os.path.join(os.path.join(os.getcwd(),'test_case_data'),'case.xlsx')
|
||||
path = os.path.join(os.path.join(os.getcwd(), 'test_case_data'), 'case.xlsx')
|
||||
basdir = os.path.abspath(os.path.dirname(__file__))
|
||||
listid, listkey, listconeent, listurl, listfangshi, listqiwang, listname = datacel(path)
|
||||
listrelust, list_fail, list_pass, list_json, list_exption, list_weizhi= testinterface()
|
||||
filepath = os.path.join(os.path.join(basdir,'test_Report'), '%s-result.html' % day)
|
||||
listrelust, list_fail, list_pass, list_json, list_exption, list_weizhi = testinterface()
|
||||
filepath = os.path.join(os.path.join(basdir, 'test_Report'), '%s-result.html' % day)
|
||||
if os.path.exists(filepath) is False:
|
||||
os.system(r'touch %s' % filepath)
|
||||
save_result(starttime, len(listrelust), ((list_pass)), list_fail)
|
||||
@@ -23,7 +23,7 @@ def stast():
|
||||
createHtml(titles='接口测试报告', filepath=filepath, starttime=starttime,
|
||||
endtime=endtime, passge=list_pass, fail=list_fail,
|
||||
id=listid, name=listname, key=listkey, coneent=listconeent, url=listurl, meth=listfangshi,
|
||||
yuqi=listqiwang, json=list_json, relusts=listrelust,exceptions=list_exption,weizhi=list_weizhi)
|
||||
yuqi=listqiwang, json=list_json, relusts=listrelust, exceptions=list_exption, weizhi=list_weizhi)
|
||||
# sendemali(filepath)
|
||||
|
||||
|
||||
|
||||
@@ -4,19 +4,23 @@ import os, datetime, time
|
||||
from testCase.case import testinterface
|
||||
from Public.py_Html import createHtml
|
||||
from Public.get_excel import datacel
|
||||
|
||||
from Public.Dingtalk import send_ding
|
||||
|
||||
'''执行测试的主要文件'''
|
||||
|
||||
|
||||
def start_interface_html_http():
|
||||
|
||||
starttime = datetime.datetime.now()
|
||||
day = time.strftime("%Y%m%d%H%M", time.localtime(time.time()))
|
||||
basdir = os.path.abspath(os.path.dirname(__file__))
|
||||
path = os.path.join(os.path.join(os.getcwd(),'test_case_data'),'case.xlsx')
|
||||
path = os.path.join(os.path.join(os.getcwd(), 'test_case_data'), 'case.xlsx')
|
||||
listid, listkey, listconeent, listurl, listfangshi, listqiwang, listname = datacel(path)
|
||||
|
||||
listrelust, list_fail, list_pass, list_json, list_exption, list_weizhi = testinterface()
|
||||
filepath = os.path.join(os.path.join(basdir , 'test_Report'),'%s-result.html' % day)
|
||||
|
||||
filepath = os.path.join(os.path.join(basdir, 'test_Report'), '%s-result.html' % day)
|
||||
if os.path.exists(filepath) is False:
|
||||
os.system(r'touch %s' % filepath)
|
||||
endtime = datetime.datetime.now()
|
||||
@@ -26,8 +30,9 @@ def start_interface_html_http():
|
||||
yuqi=listqiwang, json=list_json, relusts=listrelust, weizhi=list_weizhi, exceptions=list_exption)
|
||||
# contec = u'http接口自动化测试完成,测试通过:%s,测试失败:%s,异常:%s,未知错误:%s,详情见:%s' % (
|
||||
# list_pass, list_fail, list_exption, list_weizhi, filepath)
|
||||
# # send_ding(content=contec)
|
||||
# send_ding(content=contec)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
start_interface_html_http()
|
||||
|
||||
22
run_new.py
22
run_new.py
@@ -3,19 +3,25 @@
|
||||
from testCase.ddt_case import MyTest
|
||||
import unittest, time, os
|
||||
from Public import BSTestRunner
|
||||
BASH_DIR="history"
|
||||
|
||||
BASH_DIR = "history"
|
||||
if __name__ == '__main__':
|
||||
basedir = os.path.abspath(os.path.dirname(__file__))
|
||||
file_dir = os.path.join(basedir, 'test_Report')
|
||||
file_reslut = os.path.join(file_dir, 'caseresult.yaml')
|
||||
try:
|
||||
os.remove(file_reslut)
|
||||
except:
|
||||
pass
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(MyTest))
|
||||
now = time.strftime('%Y-%m%d', time.localtime(time.time()))
|
||||
basedir = os.path.abspath(os.path.dirname(__file__))
|
||||
file_dir = os.path.join(basedir, 'test_Report')
|
||||
file = os.path.join(file_dir, (now + '.html'))
|
||||
re_open = open(file, 'wb')
|
||||
besautiful = BSTestRunner.BSTestRunner(title="报告",
|
||||
description="测试报告",
|
||||
stream=re_open,
|
||||
trynum=3,
|
||||
filepath=BASH_DIR,
|
||||
is_show=True)
|
||||
description="测试报告",
|
||||
stream=re_open,
|
||||
trynum=3,
|
||||
filepath=BASH_DIR,
|
||||
is_show=True)
|
||||
besautiful.run(suite)
|
||||
|
||||
@@ -6,9 +6,9 @@ from Interface.testFengzhuang import TestApi
|
||||
from Public.get_excel import datacel
|
||||
from Public.log import LOG, logger
|
||||
import os
|
||||
from config.config_T import Config_Try_Num, TestPlanUrl
|
||||
from config.config import Config_Try_Num, TestPlanUrl
|
||||
|
||||
path = os.path.join(os.path.join(os.getcwd(),'test_case_data'),'case.xlsx')
|
||||
path = os.path.join(os.path.join(os.getcwd(), 'test_case_data'), 'case.xlsx')
|
||||
|
||||
listid, listkey, listconeent, listurl, listfangshi, listqiwang, listname = datacel(path)
|
||||
from Public.panduan import assert_in
|
||||
@@ -25,7 +25,10 @@ def testinterface():
|
||||
error_num = 0
|
||||
for i in range(len(listurl)):
|
||||
while error_num <= Config_Try_Num + 1:
|
||||
api = TestApi(url=TestPlanUrl + listurl[i], key=listkey[i], connent=listconeent[i], fangshi=listfangshi[i])
|
||||
parem = {'key': listkey[i]}
|
||||
parem.update({'info': eval(listconeent[i])})
|
||||
#parem=eval(data_test[listconeent[i])
|
||||
api = TestApi(url=TestPlanUrl + listurl[i], parame=parem, method=listfangshi[i])
|
||||
apijson = api.getJson()
|
||||
if apijson['code'] == 0:
|
||||
LOG.info('inputdata> 参数:%s, url:%s ,返回:%s,预期:%s' % (listconeent[i], listurl[i], apijson, listqiwang[i]))
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
import ddt, unittest,os,yaml
|
||||
from Interface.testFengzhuang import TestApi
|
||||
from Public.get_excel import makedata
|
||||
from Public.log import LOG
|
||||
from Public.panduan import assertre
|
||||
import ddt, unittest
|
||||
from config.config import TestPlanUrl
|
||||
|
||||
file_dir = os.path.join(os.getcwd(), 'test_Report')
|
||||
file_reslut = os.path.join(file_dir, 'caseresult.yaml')
|
||||
|
||||
data_test = makedata()
|
||||
|
||||
def write(data):
|
||||
with open(file_reslut, 'a', encoding='utf-8') as f:
|
||||
yaml.dump(data, f, allow_unicode=True)
|
||||
def read(data):
|
||||
f = open(file_reslut, 'r', encoding='utf-8')
|
||||
d = yaml.load(f, Loader=yaml.FullLoader)
|
||||
return d[data]
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class MyTest(unittest.TestCase):
|
||||
@@ -17,13 +29,52 @@ class MyTest(unittest.TestCase):
|
||||
|
||||
@ddt.data(*data_test)
|
||||
def test_api(self, data_test):
|
||||
api = TestApi(url=data_test['url'], key=data_test['key'], connent=data_test['coneent'],
|
||||
fangshi=data_test['fangshi'])
|
||||
'''
|
||||
1.处理参数
|
||||
2.判断参数是否有依赖
|
||||
3.依赖用例参数从本地获取
|
||||
4.获取失败,用例失败
|
||||
5.拼接后请求
|
||||
'''
|
||||
parem = {'key': data_test['key']}
|
||||
try:
|
||||
parem_dict=eval(data_test['coneent'])
|
||||
for key,value in parem_dict.items():
|
||||
if str(value).startswith("&"):
|
||||
try:
|
||||
reply_key_id=str(value).split("&")[-1].split("=")
|
||||
reply_keyid=reply_key_id[0]
|
||||
reply_key_key=reply_key_id[1]
|
||||
reslut=read(reply_keyid)
|
||||
if reslut is None:
|
||||
self.assertTrue(False,'依赖用例获取失败')
|
||||
get_value=reslut[reply_key_key]
|
||||
if get_value is None:
|
||||
self.assertTrue(False, '依赖参数获取失败,不存在')
|
||||
parem_dict[key]=get_value
|
||||
except Exception as e:
|
||||
LOG.info("用例依赖执行失败:"+str(e))
|
||||
self.assertTrue(False,'用例依赖执行失败')
|
||||
|
||||
parem.update({'info':parem_dict})
|
||||
except:
|
||||
self.assertTrue(False,msg="参数格式不对")
|
||||
|
||||
# try:
|
||||
#parem=eval(data_test['coneent'])
|
||||
# except:
|
||||
# self.assertTrue(False, msg="参数格式不对")
|
||||
api = TestApi(url=TestPlanUrl+data_test['url'],
|
||||
parame=parem,
|
||||
method=data_test['fangshi'])
|
||||
LOG.info('输入参数:url:%s,key:%s,参数:%s,请求方式:%s' % (data_test['url'], data_test['key'], data_test['coneent'],
|
||||
LOG.info('输入参数:url:%s,key:%s,参数:%s,请求方式:%s' % (
|
||||
data_test['url'], data_test['key'], data_test['coneent'],
|
||||
data_test['fangshi']))))
|
||||
data_test['url'], data_test['key'], data_test['coneent'],
|
||||
data_test['fangshi']))))
|
||||
apijson = api.getJson()
|
||||
reslut={}
|
||||
reslut[data_test['id']]=apijson
|
||||
write(reslut)
|
||||
LOG.info('返回结果:%s' % apijson)
|
||||
assertall = assertre(asserqingwang=data_test['qiwang'])
|
||||
self.assertNotEqual(dict(assertall), dict(apijson), msg='预期和返回不一致')
|
||||
|
||||
@@ -8,7 +8,8 @@ from Public.log import LOG, logger
|
||||
from Public.panduan import assert_in
|
||||
from Public.get_excel import datacel
|
||||
import os
|
||||
path =os.path.join(os.path.join(os.getcwd(),'test_case_data'),'dubbocase.xlsx')
|
||||
|
||||
path = os.path.join(os.path.join(os.getcwd(), 'test_case_data'), 'dubbocase.xlsx')
|
||||
listid, listurl, listinterface, listmeth, listfobject, listparam, listassert = datacel(path)
|
||||
|
||||
|
||||
|
||||
@@ -1,264 +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">
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
|
||||
|
||||
<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>
|
||||
<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');
|
||||
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>
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>http接口自动化测试报告</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- 引入 Bootstrap -->
|
||||
<link href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- HTML5 Shim 和 Respond.js 用于让 IE8 支持 HTML5元素和媒体查询 -->
|
||||
<!-- 注意: 如果通过 file:// 引入 Respond.js 文件,则该文件无法起效果 -->
|
||||
<!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
|
||||
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<style type="text/css">
|
||||
.hidden-detail,.hidden-tr{
|
||||
display:none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class='col-md-4 col-md-offset-4' style='margin-left:3%;'>
|
||||
<h1>接口测试的结果</h1>
|
||||
<table class="table table-hover table-condensed">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>开始时间:</strong> 2022-01-15 13:43:00.888436</td>
|
||||
</tr>
|
||||
<td><strong>结束时间:</strong> 2022-01-15 13:43:04.033432</td></tr>
|
||||
<td><strong>耗时:</strong> 0:00:03.144996</td></tr>
|
||||
<td><strong>结果:</strong>
|
||||
<span >Pass: <strong >0</strong>
|
||||
Fail: <strong >2</strong>
|
||||
exception: <strong >0</strong>
|
||||
weizhicuowu : <strong >0</strong></span></td>
|
||||
</tr>
|
||||
</tbody></table>
|
||||
</div> <div class="row " style="margin:60px">
|
||||
<div style=' margin-top: 18%;' >
|
||||
<div class="btn-group" role="group" aria-label="...">
|
||||
<button type="button" id="check-all" class="btn btn-primary">所有用例</button>
|
||||
<button type="button" id="check-success" class="btn btn-success">成功用例</button>
|
||||
<button type="button" id="check-danger" class="btn btn-danger">失败用例</button>
|
||||
<button type="button" id="check-warning" class="btn btn-warning">错误用例</button>
|
||||
<button type="button" id="check-except" class="btn btn-defult">异常用例</button>
|
||||
</div>
|
||||
<div class="btn-group" role="group" aria-label="...">
|
||||
</div>
|
||||
<table class="table table-hover table-condensed table-bordered" style="word-wrap:break-word; word-break:break-all; margin-top: 7px;">
|
||||
<tr >
|
||||
<td ><strong>用例ID </strong></td>
|
||||
<td><strong>用例名字</strong></td>
|
||||
<td><strong>key</strong></td>
|
||||
<td><strong>请求内容</strong></td>
|
||||
<td><strong>url</strong></td>
|
||||
<td><strong>请求方式</strong></td>
|
||||
<td><strong>预期</strong></td>
|
||||
<td><strong>实际返回</strong></td>
|
||||
<td><strong>结果</strong></td>
|
||||
</tr>
|
||||
|
||||
<tr class="case-tr warning">
|
||||
<td>1.0</td>
|
||||
<td>图灵api接口</td>
|
||||
<td>aaaa</td>
|
||||
<td>{'password':'1222'}</td>
|
||||
<td>/openapi/api</td>
|
||||
<td>POST</td>
|
||||
<td>code=40001</td>
|
||||
<td>{'code': 40007, 'text': '您的请求内容为空。'}</td>
|
||||
<td bgcolor="fail">fail</td>
|
||||
</tr>
|
||||
|
||||
<tr class="case-tr warning">
|
||||
<td>2.0</td>
|
||||
<td>图灵api接口</td>
|
||||
<td>dfeb1cc8125943d29764a2f2f5c33739</td>
|
||||
<td>{'password':'1222'}</td>
|
||||
<td>/openapi/api</td>
|
||||
<td>POST</td>
|
||||
<td>code=40002</td>
|
||||
<td>{'code': 40007, 'text': '您的请求内容为空。'}</td>
|
||||
<td bgcolor="fail">fail</td>
|
||||
</tr>
|
||||
</div></div></table><script src="https://code.jquery.com/jquery.js"></script>
|
||||
<script src="https://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
$("#check-danger").click(function(e){
|
||||
$(".case-tr").removeClass("hidden-tr");
|
||||
$(".success").addClass("hidden-tr");
|
||||
$(".warning").addClass("hidden-tr");
|
||||
$(".error").addClass("hidden-tr");
|
||||
});
|
||||
$("#check-warning").click(function(e){
|
||||
$(".case-tr").removeClass("hidden-tr");
|
||||
$(".success").addClass("hidden-tr");
|
||||
$(".danger").addClass("hidden-tr");
|
||||
$(".error").addClass("hidden-tr");
|
||||
});
|
||||
$("#check-success").click(function(e){
|
||||
$(".case-tr").removeClass("hidden-tr");
|
||||
$(".warning").addClass("hidden-tr");
|
||||
$(".danger").addClass("hidden-tr");
|
||||
$(".error").addClass("hidden-tr");
|
||||
});
|
||||
$("#check-except").click(function(e){
|
||||
$(".case-tr").removeClass("hidden-tr");
|
||||
$(".warning").addClass("hidden-tr");
|
||||
$(".danger").addClass("hidden-tr");
|
||||
$(".success").addClass("hidden-tr");
|
||||
});
|
||||
$("#check-all").click(function(e){
|
||||
$(".case-tr").removeClass("hidden-tr");
|
||||
});
|
||||
</script>
|
||||
</body></html>
|
||||
Reference in New Issue
Block a user