Browse Source

commit

test
jshixiong 1 year ago
commit
32724305e0
84 changed files with 2744 additions and 0 deletions
  1. +2
    -0
      .idea/.gitignore
  2. +6
    -0
      .idea/inspectionProfiles/profiles_settings.xml
  3. +15
    -0
      .idea/jiekou-python3.iml
  4. +7
    -0
      .idea/misc.xml
  5. +8
    -0
      .idea/modules.xml
  6. +6
    -0
      .idea/vcs.xml
  7. +0
    -0
      Interface/__init__.py
  8. +29
    -0
      Interface/dubbo_feng.py
  9. +29
    -0
      Interface/testFengzhuang.py
  10. +1
    -0
      Interface/test_requests.py
  11. +1021
    -0
      Public/BSTestRunner.py
  12. +27
    -0
      Public/Dingtalk.py
  13. +6
    -0
      Public/__init__.py
  14. +18
    -0
      Public/create_report.py
  15. +35
    -0
      Public/emmail.py
  16. +36
    -0
      Public/fengzhuang_dict.py
  17. +50
    -0
      Public/get_excel.py
  18. +20
    -0
      Public/get_excel_new.py
  19. +47
    -0
      Public/log.py
  20. +32
    -0
      Public/panduan.py
  21. +180
    -0
      Public/py_Html.py
  22. +113
    -0
      Public/pyreport_excel.py
  23. +1
    -0
      Public/test_requests.py
  24. +37
    -0
      README.md
  25. +5
    -0
      config/__init__.py
  26. +8
    -0
      config/config.py
  27. +4
    -0
      config/email.yaml
  28. +7
    -0
      config/test_report.yaml
  29. +1
    -0
      history/2022_01_15_14_26_21.txt
  30. +1
    -0
      history/2022_01_16_09_36_13.txt
  31. +1
    -0
      history/2022_01_16_09_38_16.txt
  32. +1
    -0
      history/2022_01_16_09_39_12.txt
  33. +1
    -0
      history/2022_01_16_09_39_32.txt
  34. +1
    -0
      history/2022_01_16_09_39_51.txt
  35. +1
    -0
      history/2022_01_16_09_41_00.txt
  36. +1
    -0
      history/2022_01_16_09_41_37.txt
  37. +1
    -0
      history/2022_01_16_09_42_37.txt
  38. +1
    -0
      history/2022_01_16_09_43_15.txt
  39. +1
    -0
      history/2022_01_16_09_43_50.txt
  40. +1
    -0
      history/2022_01_16_09_43_56.txt
  41. +1
    -0
      history/2022_01_16_09_44_26.txt
  42. +1
    -0
      history/2022_01_16_09_44_35.txt
  43. +1
    -0
      history/2022_01_16_09_45_12.txt
  44. +1
    -0
      history/2022_01_16_09_46_33.txt
  45. +1
    -0
      history/2022_04_22_17_22_51.txt
  46. +1
    -0
      history/2022_04_22_21_06_05.txt
  47. +1
    -0
      history/2022_04_22_21_22_01.txt
  48. +1
    -0
      history/2022_04_22_21_29_08.txt
  49. +1
    -0
      history/2022_04_22_21_32_40.txt
  50. +1
    -0
      history/2023_02_19_18_06_29.txt
  51. +1
    -0
      history/2023_02_19_18_08_39.txt
  52. +1
    -0
      history/2023_02_19_18_10_30.txt
  53. +1
    -0
      history/2023_02_19_18_10_47.txt
  54. BIN
      img/cebaogaotu.png
  55. BIN
      img/excel.png
  56. BIN
      img/excel2.png
  57. BIN
      img/kongzhitai.PNG
  58. BIN
      img/log.png
  59. BIN
      img/weixin.png
  60. BIN
      img/xiangmujiegoutu.png
  61. BIN
      img/xinbanbenlog.png
  62. BIN
      img/公众号海报.jpeg
  63. BIN
      img/新版本测试报告.png
  64. +48
    -0
      log/interface_case_run-2023_02_19_18.log
  65. +44
    -0
      log/interface_case_run-2023_02_28_15.log
  66. +27
    -0
      result.txt
  67. +38
    -0
      run_excel_re.py
  68. +36
    -0
      run_html.py
  69. +38
    -0
      run_http_html.py
  70. +27
    -0
      run_new.py
  71. +0
    -0
      testCase/__init__.py
  72. +86
    -0
      testCase/case.py
  73. +79
    -0
      testCase/ddt_case.py
  74. +52
    -0
      testCase/dubbocase.py
  75. +64
    -0
      testCase/pytestCasetest.py
  76. +264
    -0
      test_Report/2023-0219.html
  77. BIN
      test_Report/20230219-result.xls
  78. +117
    -0
      test_Report/202302191806-result.html
  79. BIN
      test_Report/20230228-result.xls
  80. +10
    -0
      test_Report/caseresult.yaml
  81. BIN
      test_case_data/case.xlsx
  82. BIN
      test_case_data/dubbocase.xlsx
  83. +38
    -0
      yesy
  84. +1
    -0
      yesy.pub

+ 2
- 0
.idea/.gitignore View File

@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

+ 6
- 0
.idea/inspectionProfiles/profiles_settings.xml View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

+ 15
- 0
.idea/jiekou-python3.iml View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="pytest" />
</component>
</module>

+ 7
- 0
.idea/misc.xml View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
</project>

+ 8
- 0
.idea/modules.xml View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/jiekou-python3.iml" filepath="$PROJECT_DIR$/.idea/jiekou-python3.iml" />
</modules>
</component>
</project>

+ 6
- 0
.idea/vcs.xml View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

+ 0
- 0
Interface/__init__.py View File


+ 29
- 0
Interface/dubbo_feng.py View File

@@ -0,0 +1,29 @@
"""
@author: lileilei
@file: dubbo_feng.py
@time: 2018/3/29 12:26
"""
from pyhessian.client import HessianProxy
from pyhessian import protocol
from public.log import LOG, logger


@logger('dubbo接口')
class DubboInterface:
def __init__(self, url, interface, method, param, **kwargs):
self.url = url
self.interface = interface
self.method = method
self.param = param
self.interfaceparam = protocol.object_factory(self.param, **kwargs)

def getresult(self):
try:
result = HessianProxy(self.url + self.interface)
return_result = getattr(result, self.method)(self.interfaceparam)
LOG.info('测试返回结果:%s' % return_result)
res = {'code': 0, 'result': return_result}
except Exception as e:
LOG.info('测试失败,原因:%s' % e)
res = {'code': 1, 'result': e}
return res

+ 29
- 0
Interface/testFengzhuang.py View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# @Time : 2017/6/4 20:36
# @Author : lileilei
# @Site :
# @File : testFengzhuang.py
from Public.test_requests import requ


class TestApi(object):
def __init__(self, url, parame, method):
self.url = url
self.parame = parame
self.method = method
self.reques = requ()

def testapi(self):
if self.method == 'POST':
self.response = self.reques.post(self.url, self.parame)
elif self.method == "GET":
self.response = self.reques.get(url=self.url, params=self.parame)
elif self.method == "PUT":
self.response = self.reques.putparams(url=self.url, params=self.parame)
elif self.method == "DELETE":
self.response = self.reques.delparams(url=self.url, params=self.parame)
return self.response

def getJson(self):
json_data = self.testapi()
return json_data

+ 1
- 0
Interface/test_requests.py View File

@@ -0,0 +1 @@
# -*- coding: utf-8 -*- # @Author : leizi import requests, json from public.log import LOG, logger @logger('requests封装') class requ(): def __init__(self): self.headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:51.0) Gecko/20100101 Firefox/51.0"} def get(self, url): # get消息 try: r = requests.get(url, headers=self.headers) r.encoding = 'UTF-8' json_response = json.loads(r.text) return json_response except Exception as e: LOG.info('get请求出错,出错原因:%s' % e) print('get请求出错,出错原因:%s' % e) return {} def post(self, url, params): # post消息 data = json.dumps(params) try: r = requests.post(url, params=params, headers=self.headers) json_response = json.loads(r.text) return json_response except Exception as e: LOG.info('post请求出错,出错原因:%s' % e) print('post请求出错,原因:%s' % e) def delfile(self, url, params): # 删除的请求 try: del_word = requests.delete(url, params, headers=self.headers) json_response = json.loads(del_word.text) return json_response except Exception as e: LOG.info('del请求出错,出错原因:%s' % e) print('del请求出错,原因:%s' % e) return {} def putfile(self, url, params): # put请求 try: data = json.dumps(params) me = requests.put(url, data) json_response = json.loads(me.text) return json_response except Exception as e: LOG.info('put请求出错,出错原因:%s' % e) print('put请求出错,原因:%s' % e) return json_response

+ 1021
- 0
Public/BSTestRunner.py
File diff suppressed because it is too large
View File


+ 27
- 0
Public/Dingtalk.py View File

@@ -0,0 +1,27 @@
"""
@author: lileilei
@file: Dingtalk.py
@time: 2017/12/26 17:34
"""
'''封装钉钉群发消息'''
import requests, json
from config.config import Dingtalk_access_token


def send_ding(content):
url = Dingtalk_access_token
pagrem = {
"msgtype": "text",
"text": {
"content": content
},
"isAtAll": True
}
headers = {
'Content-Type': 'application/json'
}
f = requests.post(url, data=json.dumps(pagrem), headers=headers)
if f.status_code == 200:
return True
else:
return False

+ 6
- 0
Public/__init__.py View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# @Time : 2017/6/4 17:34
# @Author : lileilei
# @Site :
# @File : __init__.py.py
# @Software: PyCharm

+ 18
- 0
Public/create_report.py View File

@@ -0,0 +1,18 @@
# encoding: utf-8
"""
@author: lileilei
@file: create_report.py
@time: 2017/8/3 12:27
"""
from Public.log import LOG, logger


@logger('保存测试结果')
def save_result(testtime, toial, passnum, fail):
try:
f = open('result.txt', 'a')
f.write("%s=%s=%s=%s \n" % (testtime, toial, passnum, fail))
f.close()
except:
LOG.info('保存测试结果出错,原因:%s' % Exception)
print('记录测试结果失败')

+ 35
- 0
Public/emmail.py View File

@@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# @Author : leizi
import smtplib, time, os
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import yaml


def load_emil_setting(): # 从配置文件中加载获取email的相关信息
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'])


def sendemali(filepath): # 发送email
from_addr, password, mail_to, mail_body = load_emil_setting()
msg = MIMEMultipart()
msg['Subject'] = '接口自动化测试报告'
msg['From'] = '自动化测试平台'
msg['To'] = mail_to
msg['Date'] = time.strftime('%a, %d %b %Y %H:%M:%S %z')
att = MIMEText(open(r'%s' % filepath, 'rb').read(), 'base64', 'utf-8')
att["Content-Type"] = 'application/octet-stream'
att["Content-Disposition"] = 'attachment; filename="pyresult.html"'
txt = MIMEText("这是测试报告的邮件,详情见附件", 'plain', 'gb2312')
msg.attach(txt)
msg.attach(att)
smtp = smtplib.SMTP()
server = smtplib.SMTP_SSL("smtp.qq.com", 465)
server.login(from_addr, password)
server.sendmail(from_addr, mail_to, msg.as_string())
server.quit()

+ 36
- 0
Public/fengzhuang_dict.py View File

@@ -0,0 +1,36 @@
"""
@author: lileilei
@file: python_dict.py
@time: 2018/6/15 13:54
"""
'''字典取值'''


def res(d, code):
result = []
if isinstance(d, dict) and code in d.keys():
value = d[code]
result.append(value)
return result
elif isinstance(d, (list, tuple)):
for item in d:
value = res(item, code)
if value == "None" or value is None:
pass
elif len(value) == 0:
pass
else:
result.append(value)
return result
else:
if isinstance(d, dict):
for k in d:
value = res(d[k], code)
if value == "None" or value is None:
pass
elif len(value) == 0:
pass
else:
for item in value:
result.append(item)
return result

+ 50
- 0
Public/get_excel.py View File

@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# @Time : 2017/6/4 20:35
# @Author : lileilei
# @File : get_excel.py
import xlrd, os
from Public.log import LOG, logger


@logger('解析测试用例文件')
def datacel(filepath):
try:
file = xlrd.open_workbook(filepath)
print(file)
rslut = file.sheets()[0]
nrows = rslut.nrows
listid = []
listkey = []
listconeent = []
listurl = []
listmethod = []
listassert = []
listname = []
for i in range(1, nrows):
listid.append(rslut.cell(i, 0).value)
listkey.append(rslut.cell(i, 2).value)
listconeent.append(rslut.cell(i, 3).value)
listurl.append(rslut.cell(i, 4).value)
listname.append(rslut.cell(i, 1).value)
listmethod.append((rslut.cell(i, 5).value))
listassert.append((rslut.cell(i, 6).value))
return listid, listkey, listconeent, listurl, listmethod, listassert, listname
except Exception as e:
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, listmethod, listassert, listname = datacel(path)
make_data = []
for i in range(len(listid)):
make_data.append({'url': listurl[i], 'key': listkey[i],
'coneent': listconeent[i], 'method': listmethod[i],
'assertconnect': listassert[i],
'id': listid[i]},
)
i += 1
return make_data

+ 20
- 0
Public/get_excel_new.py View File

@@ -0,0 +1,20 @@
"""
@author: lileilei
@file: get_excel_new.py
@time: 2018/4/30 11:04
"""
'''读取Excel'''
import xlrd


def datacel(filrpath):
all_case = []
file = xlrd.open_workbook(filrpath)
me = file.sheets()[0]
nrows = me.nrows
for i in range(1, nrows):
all_case.append({"id": me.cell(i, 0).value, 'key': me.cell(i, 2).value,
'coneent': me.cell(i, 3).value, 'url': me.cell(i, 4).value,
'name': me.cell(i, 1).value, 'fangshi': me.cell(i, 5).value,
'assert': me.cell(i, 6).value})
return all_case

+ 47
- 0
Public/log.py View File

@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
# @Date : 2017-10-14 15:35:17
# @Author : leizi
'''日志模块'''
import os
import logbook
from logbook.more import ColorizedStderrHandler
from functools import wraps

check_path = '.'
LOG_DIR = os.path.join(check_path, 'log')
file_stream = False
if not os.path.exists(LOG_DIR):
os.makedirs(LOG_DIR)
file_stream = True


def get_logger(name='interface_case_run', file_log=file_stream, level=''):
""" get logger Factory function """
logbook.set_datetime_format('local')
ColorizedStderrHandler(bubble=False, level=level).push_thread()
logbook.TimedRotatingFileHandler(
os.path.join(LOG_DIR, '%s.log' % name),
date_format='%Y_%m_%d_%H', bubble=True, encoding='utf-8').push_thread()
return logbook.Logger(name)


LOG = get_logger(file_log=file_stream, level='INFO')


def logger(param):
""" fcuntion from logger meta """

def wrap(function):
""" logger wrapper """

@wraps(function)
def _wrap(*args, **kwargs):
""" wrap tool """
LOG.info("当前模块 {}".format(param))
LOG.info("全部args参数参数信息 , {}".format(str(args)))
LOG.info("全部kwargs参数信息 , {}".format(str(kwargs)))
return function(*args, **kwargs)

return _wrap

return wrap

+ 32
- 0
Public/panduan.py View File

@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# @Date : 2017-08-02 21:54:08
# @Author : lileilei
from Public.fengzhuang_dict import res
from .log import LOG, logger


@logger('断言测试结果')
def assert_in(asserassert, returnjson):
if len(asserassert.split('=')) > 1:
data = asserassert.split('&')
result = dict([(item.split('=')) for item in data])
value1 = ([(str(res(returnjson, key))) for key in result.keys()])
value2 = ([(str(value)) for value in result.values()])
if value1 == value2:
return {'code': 0, "result": 'pass'}
else:
return {'code': 1, 'result': 'fail'}
else:
LOG.info('填写测试预期值')
return {"code": 2, 'result': '填写测试预期值'}


@logger('断言测试结果')
def assertre(asserassert):
if len(asserassert.split('=')) > 1:
data = asserassert.split('&')
result = dict([(item.split('=')) for item in data])
return result
else:
LOG.info('填写测试预期值')
raise {"code": 1, 'result': '填写测试预期值'}

+ 180
- 0
Public/py_Html.py View File

@@ -0,0 +1,180 @@
# encoding: utf-8
"""
@author: lileilei
@file: py_Html.py
@time: 2017/6/5 17:04
"""

titles = '接口测试'


def title(titles):
title = '''<!DOCTYPE html>
<html>
<head>
<title>%s</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>
''' % (titles)
return title


connent = '''
<div class='col-md-4 col-md-offset-4' style='margin-left:3%;'>
<h1>接口测试的结果</h1>'''


def shouye(starttime, endtime, passge, fail, excepthions, weizhicuowu):
beijing = '''
<table class="table table-hover table-condensed">
<tbody>
<tr>
<td><strong>开始时间:</strong> %s</td>
</tr>
<td><strong>结束时间:</strong> %s</td></tr>
<td><strong>耗时:</strong> %s</td></tr>
<td><strong>结果:</strong>
<span >Pass: <strong >%s</strong>
Fail: <strong >%s</strong>
exception: <strong >%s</strong>
weizhicuowu : <strong >%s</strong></span></td>
</tr>
</tbody></table>
</div> ''' % (starttime, endtime, (endtime - starttime), passge, fail, excepthions, weizhicuowu)
return beijing


shanghai = '''<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&nbsp;</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>
'''


def passfail(tend):
if tend == 'pass':
htl = '''<td bgcolor="green">pass</td>'''
elif tend == 'fail':
htl = '''<td bgcolor="fail">fail</td>'''
elif tend == 'weizhi':
htl = '''<td bgcolor="red">error</td>'''
else:
htl = '<td bgcolor="crimson">exect</td>'
return htl


def ceshixiangqing(reslt, id, name, key, coneent, url, meth, yuqi, json, relust):
xiangqing = '''
<tr class="case-tr %s">
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
%s
</tr>
''' % (reslt, id, name, key, coneent, url, meth, yuqi, json, passfail(relust))
return xiangqing


weibu = '''</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>'''


def relust(titles, starttime, endtime, passge, fail, id, name, key, coneent, url, meth, yuqi, json, relust, exceptions,
weizhi):
if type(name) == list:
relus = ' '
for i in range(len(name)):
if relust[i] == "pass":
clazz = "success"
elif relust[i] == "fail":
clazz = "warning"
elif relust[i] == "weizhi":
clazz = "danger"
else:
clazz = 'error'
relus += (
ceshixiangqing(clazz, id[i], name[i], key[i], coneent[i], url[i], meth[i], yuqi[i], json[i], relust[i]))
text = title(titles) + connent + shouye(starttime, endtime, passge, fail, exceptions,
weizhi) + shanghai + relus + weibu
else:
text = title(titles) + connent + shouye(starttime, endtime, passge, fail, exceptions,
weizhi) + shanghai + ceshixiangqing(id, name, key, coneent, url, meth,
yuqi, json, relust) + weibu
return text


def createHtml(filepath, titles, starttime, endtime, passge, fail, id, name, key, coneent, url, meth, yuqi, json,
relusts, exceptions, weizhi):
texts = relust(titles, starttime, endtime, passge, fail, id, name, key, coneent, url, meth, yuqi, json, relusts,
exceptions, weizhi)
with open(filepath, 'wb') as f:
f.write(texts.encode('utf-8'))

+ 113
- 0
Public/pyreport_excel.py View File

@@ -0,0 +1,113 @@
# encoding: utf-8
"""
@author: lileilei
@file: pyreport_excel.py
@time: 2017/6/7 8:47
"""
import os, xlwt, yaml
from xlwt import *


def yangshi1():
style = XFStyle()
fnt = Font()
fnt.name = u'微软雅黑'
fnt.bold = True
style.font = fnt
alignment = xlwt.Alignment()
alignment.horz = xlwt.Alignment.HORZ_CENTER
alignment.vert = xlwt.Alignment.VERT_CENTER
style.alignment = alignment # 给样式添加文字居中属性
style.font.height = 430 # 设置字体大小
return style


def yangshi2():
style1 = XFStyle()
alignment = xlwt.Alignment()
alignment.horz = xlwt.Alignment.HORZ_CENTER
alignment.vert = xlwt.Alignment.VERT_CENTER
style1.alignment = alignment # 给样式添加文字居中属性
style1.font.height = 330 # 设置字体大小
return style1


def yangshi3():
style1 = XFStyle()
style1.font.height = 330 # 设置字体大小
return style1


def yangshique(me):
if me == 'pass':
style = yangshi1()
Pattern = xlwt.Pattern()
Pattern.pattern = xlwt.Pattern.SOLID_PATTERN
Pattern.pattern_fore_colour = xlwt.Style.colour_map['green']
style.pattern = Pattern
else:
style = yangshi2()
Pattern = xlwt.Pattern()
Pattern.pattern = xlwt.Pattern.SOLID_PATTERN
Pattern.pattern_fore_colour = xlwt.Style.colour_map['red']
style.pattern = Pattern
return style


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)
file = Workbook(filename)
table = file.add_sheet('测试结果', cell_overwrite_ok=True)
style = yangshi1()
for i in range(0, 7):
table.col(i).width = 380 * 20
style1 = yangshi2()
table.write_merge(0, 0, 0, 6, '测试报告', style=style)
table.write_merge(1, 1, 0, 6, '', style=style)
table.write_merge(2, 3, 0, 6, '测试详情', style=style1)
table.write(4, 0, '项目名称', style=style1)
table.write(5, 0, '接口版本', style=style1)
table.write(6, 0, '提测时间', style=style1)
table.write(7, 0, '提测人', style=style1)
table.write(4, 2, '测试人', style=style1)
table.write(5, 2, '测试时间', style=style1)
table.write(6, 2, '审核人', style=style1)
table.write(4, 4, '通过', style=style1)
table.write(5, 4, '失败', style=style1)
table.write(6, 4, '成功率', style=style1)
table.write(4, 1, (file_config['projectname']), style=style1)
table.write(5, 1, file_config['interfaceVersion'], style=style1)
table.write(6, 1, file_config['tijiao_time'], style=style1)
table.write(7, 1, file_config['tijiao_person'], style=style1)
table.write(4, 3, file_config['ceshi_person'], style=style1)
table.write(5, 3, file_config['ceshi_time'], style=style1)
table.write(6, 3, file_config['shenhename'], style=style1)
table.write(4, 5, (list_pass), style=style1)
table.write(5, 5, (list_fail), style=style1)
table.write(6, 5, ('%.2f%%' % ((list_pass) / (len(listrelust)))), style=style1)
table1 = file.add_sheet('测试详情', cell_overwrite_ok=True)
table1.write_merge(0, 0, 0, 8, '测试详情', style=style)
for i in range(0, 8):
table1.col(i).width = 400 * 20
table1.write(1, 0, '用例ID', style=yangshi3())
table1.write(1, 1, '用例名字', style=yangshi3())
table1.write(1, 2, 'key', style=yangshi3())
table1.write(1, 3, '请求内容', style=yangshi3())
table1.write(1, 4, ' url', style=yangshi3())
table1.write(1, 5, '请求方式', style=yangshi3())
table1.write(1, 6, '预期', style=yangshi3())
table1.write(1, 7, '实际返回', style=yangshi3())
table1.write(1, 8, '结果', style=yangshi3())
for i in range(len(listids)):
table1.write(i + 1, 0, listids[i], style=yangshi3())
table1.write(i + 1, 1, listnames[i], style=yangshi3())
table1.write(i + 1, 2, listkeys[i], style=yangshi3())
table1.write(i + 1, 3, listconeents[i], style=yangshi3())
table1.write(i + 1, 4, listurls[i], style=yangshi3())
table1.write(i + 1, 5, listfangshis[i], style=yangshi3())
table1.write(i + 1, 6, listqiwangs[i], style=yangshi3())
table1.write(i + 1, 7, str(list_json[i]), style=yangshi3())
table1.write(i + 1, 8, listrelust[i], style=yangshique(listrelust[i]))
file.save(filename)

+ 1
- 0
Public/test_requests.py View File

@@ -0,0 +1 @@
# -*- coding: utf-8 -*- # @Author : leizi import requests, json from requests import Timeout, RequestException class requ(): def __init__(self): self.headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:51.0) Gecko/20100101 Firefox/51.0"} def get(self, url, params): # get消息 try: r = requests.get(url, params=params, headers=self.headers) r.encoding = 'UTF-8' if r.status_code == 200: json_response = json.loads(r.text) return {'code': 0, 'result': json_response} else: return {'code': 1, 'result': '接口请求失败,返回状态码:%s' % str(r.status_code)} except Timeout as e: return {'code': 1, 'result': '请求超时:%s' % e} except RequestException as e: return {'code': 1, 'result': '请求异常:%s' % e} except Exception as e: return {'code': 1, 'result': 'get请求出错,出错原因:%s' % e} def post(self, url, params): # post消息 data = json.dumps(params) try: r = requests.post(url, params=data, headers=self.headers) if r.status_code == 200: json_response = json.loads(r.text) return {'code': 0, 'result': json_response} else: return {'code': 1, 'result': '接口请求失败,返回状态码:%s' % str(r.status_code)} except Timeout as e: return {'code': 1, 'result': '请求超时:%s' % e} except RequestException as e: return {'code': 1, 'result': '请求异常:%s' % e} except Exception as e: return {'code': 1, 'result': 'post请求出错,出错原因:%s' % e} def delparams(self, url, params): # 删除的请求 try: del_word = requests.delete(url, params=params, headers=self.headers) if del_word.status_code == 200: json_response = json.loads(del_word.text) return {'code': 0, 'result': json_response} else: return {'code': 1, 'result': '接口请求失败,返回状态码:%s' % str(del_word.status_code)} except Timeout as e: return {'code': 1, 'result': '请求超时:%s' % e} except RequestException as e: return {'code': 1, 'result': '请求异常:%s' % e} except Exception as e: return {'code': 1, 'result': 'del请求出错,出错原因:%s' % e} def putparams(self, url, params): # put请求 try: data = json.dumps(params) result = requests.put(url, data) if result.status_code == 200: json_response = json.loads(result.text) return {'code': 0, 'result': json_response} else: return {'code': 1, 'result': '接口请求失败,返回状态码:%s' % str(result.status_code)} except Timeout as e: return {'code': 1, 'result': '请求超时:%s' % e} except RequestException as e: return {'code': 1, 'result': '请求异常:%s' % e} except Exception as e: return {'code': 1, 'result': 'put请求出错,出错原因:%s' % e}

+ 37
- 0
README.md View File

@@ -0,0 +1,37 @@
# 接口测试框架(基于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原有的库进行的,这样简单方便,
### 使用脚本参数分离等思想,尽可能降低代码的耦合度。
### 如果你不配置钉钉机器人,注释到机器人相关的代码
# 首先我们来看下我们的目录
##
![Alt text](https://github.com/liwanlei/jiekou-python3/blob/master/img/xiangmujiegoutu.png)
##
### 1.Case文件夹用来存放我们的测试用例相关的,
### 2.test_case用来存储我们的测试数据,Excel管理测试用例,yaml文件管理测试用例,后续要把yaml管理测试用例的也封装出来。
### 3.Interface对测试接口相关的封装,包括requests库,发送测试报告的email的封装,从Excel取测试数据的封装
### 4.Public 展示测试报告相关的脚本,这里可以自己封装,也可以使用现成的,我这里是基于我自己封装的,最后生成的测试报告更加易懂,出错可以尽快排查相关原因
### 5.report 存放测试报告,
### 6.run_excel_re.py/run_html.py 主运行文件。运行后可以生成相应的测试报告
### 7.run_new新版执行方式,重写了unittest方法,利用ddt驱动,生成漂亮的测试报告
##
## 除了在github的开源项目的分享,我也运营了自己的公众号,欢迎大家关注我的公众号
![Alt text](https://github.com/liwanlei/jiekou-python3/blob/master/img/%E5%85%AC%E4%BC%97%E5%8F%B7%E6%B5%B7%E6%8A%A5.jpeg)
## 产生的html测试报告如下
![Alt text](https://github.com/liwanlei/jiekou/blob/master/img/cebaogaotu.png)
##
### 增加了Excel管理测试报告的功能,目前在继续优化功能,增加了config目录,一些配置文件的目录,
##
## 产生的Excel测试报告如下
![Alt text](https://github.com/liwanlei/jiekou/blob/master/img/excel.png)
![Alt text](https://github.com/liwanlei/jiekou/blob/master/img/excel2.png)
### 现在的测试结构更加完整,最新的一次提交增加了log日志的展示,使功能更加完善,log日志在控制台展示如下,对目录进行优化
![Alt text](https://github.com/liwanlei/jiekou/blob/master/img/log.png)




+ 5
- 0
config/__init__.py View File

@@ -0,0 +1,5 @@
"""
@author: lileilei
@file: __init__.py
@time: 2018/4/12 14:17
"""

+ 8
- 0
config/config.py View File

@@ -0,0 +1,8 @@
"""
@author: lileilei
@file: config.py
@time: 2018/4/12 14:17
"""
Dingtalk_access_token = "" # 钉钉配置
TestPlanUrl = 'http://localhost:8881' # 基础url
Config_Try_Num = 1 # 失败重试

+ 4
- 0
config/email.yaml View File

@@ -0,0 +1,4 @@
#foremail: '952943386@qq.com'
#password: "zzaikjtenujtbaif"
#toeamil: "leileili126@163.com,952943386@qq.com"
title: "测试报告"

+ 7
- 0
config/test_report.yaml View File

@@ -0,0 +1,7 @@
projectname: '图灵'
interfaceVersion: '1.0.1'
tijiao_time: 2023-1-28
tijiao_person: testTJ
ceshi_person: test1,test2
ceshi_time: 2023-2-28
shenhename: shenhe1

+ 1
- 0
history/2022_01_15_14_26_21.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_36_13.txt View File

@@ -0,0 +1 @@
0_2_0

+ 1
- 0
history/2022_01_16_09_38_16.txt View File

@@ -0,0 +1 @@
0_2_0

+ 1
- 0
history/2022_01_16_09_39_12.txt View File

@@ -0,0 +1 @@
0_2_0

+ 1
- 0
history/2022_01_16_09_39_32.txt View File

@@ -0,0 +1 @@
0_2_0

+ 1
- 0
history/2022_01_16_09_39_51.txt View File

@@ -0,0 +1 @@
0_2_0

+ 1
- 0
history/2022_01_16_09_41_00.txt View File

@@ -0,0 +1 @@
0_2_0

+ 1
- 0
history/2022_01_16_09_41_37.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_42_37.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_43_15.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_43_50.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_43_56.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_44_26.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_44_35.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_45_12.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_01_16_09_46_33.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_04_22_17_22_51.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_04_22_21_06_05.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_04_22_21_22_01.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_04_22_21_29_08.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2022_04_22_21_32_40.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2023_02_19_18_06_29.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2023_02_19_18_08_39.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2023_02_19_18_10_30.txt View File

@@ -0,0 +1 @@
2_0_0

+ 1
- 0
history/2023_02_19_18_10_47.txt View File

@@ -0,0 +1 @@
2_0_0

BIN
img/cebaogaotu.png View File

Before After
Width: 1273  |  Height: 568  |  Size: 61 kB

BIN
img/excel.png View File

Before After
Width: 1465  |  Height: 849  |  Size: 14 kB

BIN
img/excel2.png View File

Before After
Width: 1784  |  Height: 636  |  Size: 73 kB

BIN
img/kongzhitai.PNG View File

Before After
Width: 1316  |  Height: 347  |  Size: 59 kB

BIN
img/log.png View File

Before After
Width: 967  |  Height: 530  |  Size: 90 kB

BIN
img/weixin.png View File

Before After
Width: 724  |  Height: 718  |  Size: 264 kB

BIN
img/xiangmujiegoutu.png View File

Before After
Width: 259  |  Height: 700  |  Size: 26 kB

BIN
img/xinbanbenlog.png View File

Before After
Width: 1003  |  Height: 626  |  Size: 110 kB

BIN
img/公众号海报.jpeg View File

Before After
Width: 1080  |  Height: 1920  |  Size: 368 kB

BIN
img/新版本测试报告.png View File

Before After
Width: 1133  |  Height: 458  |  Size: 19 kB

+ 48
- 0
log/interface_case_run-2023_02_19_18.log View File

@@ -0,0 +1,48 @@
[2023-02-19 18:10:29.859856] INFO: interface_case_run: 当前模块 生成数据驱动所用数据
[2023-02-19 18:10:29.860589] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-19 18:10:29.860726] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-19 18:10:29.860902] INFO: interface_case_run: 当前模块 解析测试用例文件
[2023-02-19 18:10:29.861022] INFO: interface_case_run: 全部args参数参数信息 , ('/Users/lileilei/Desktop/testplan/jiekou-python3/test_case_data/case.xlsx',)
[2023-02-19 18:10:29.861131] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-19 18:10:29.890171] INFO: interface_case_run: 测试用例开始执行
[2023-02-19 18:10:29.890499] INFO: interface_case_run: {'key': 'aaaa', 'info': {'password': '1222'}}
[2023-02-19 18:10:29.890675] INFO: interface_case_run: 输入参数:url:/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:POST
[2023-02-19 18:10:29.890808] INFO: interface_case_run: 输入参数:url:/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:None
[2023-02-19 18:10:29.963764] INFO: interface_case_run: 返回结果:{'code': 0, 'result': {'code': 40007, 'text': '您的请求内容为空。'}}
[2023-02-19 18:10:29.964209] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-19 18:10:29.964440] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-19 18:10:29.964621] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=40001'}
[2023-02-19 18:10:29.964853] INFO: interface_case_run: 测试用例执行完毕
[2023-02-19 18:10:29.965177] INFO: interface_case_run: 测试用例开始执行
[2023-02-19 18:10:29.965522] INFO: interface_case_run: {'key': 'dfeb1cc8125943d29764a2f2f5c33739', 'info': {'password': '1222'}}
[2023-02-19 18:10:29.965771] INFO: interface_case_run: 输入参数:url:/openapi/api,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:POST
[2023-02-19 18:10:29.965956] INFO: interface_case_run: 输入参数:url:/openapi/api,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:None
[2023-02-19 18:10:30.008491] INFO: interface_case_run: 返回结果:{'code': 0, 'result': {'code': 40007, 'text': '您的请求内容为空。'}}
[2023-02-19 18:10:30.008802] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-19 18:10:30.009003] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-19 18:10:30.009179] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=40002'}
[2023-02-19 18:10:30.009398] INFO: interface_case_run: 测试用例执行完毕
[2023-02-19 18:10:47.409761] INFO: interface_case_run: 当前模块 生成数据驱动所用数据
[2023-02-19 18:10:47.410094] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-19 18:10:47.410218] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-19 18:10:47.410376] INFO: interface_case_run: 当前模块 解析测试用例文件
[2023-02-19 18:10:47.410492] INFO: interface_case_run: 全部args参数参数信息 , ('/Users/lileilei/Desktop/testplan/jiekou-python3/test_case_data/case.xlsx',)
[2023-02-19 18:10:47.410600] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-19 18:10:47.430403] INFO: interface_case_run: 测试用例开始执行
[2023-02-19 18:10:47.430650] INFO: interface_case_run: {'key': 'aaaa', 'info': {'password': '1222'}}
[2023-02-19 18:10:47.430796] INFO: interface_case_run: 输入参数:url:/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:POST
[2023-02-19 18:10:47.430936] INFO: interface_case_run: 输入参数:url:/openapi/api,key:aaaa,参数:{'password':'1222'},请求方式:None
[2023-02-19 18:10:47.481670] INFO: interface_case_run: 返回结果:{'code': 0, 'result': {'code': 40007, 'text': '您的请求内容为空。'}}
[2023-02-19 18:10:47.482034] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-19 18:10:47.482468] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-19 18:10:47.482886] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=40001'}
[2023-02-19 18:10:47.483244] INFO: interface_case_run: 测试用例执行完毕
[2023-02-19 18:10:47.483554] INFO: interface_case_run: 测试用例开始执行
[2023-02-19 18:10:47.483789] INFO: interface_case_run: {'key': 'dfeb1cc8125943d29764a2f2f5c33739', 'info': {'password': '1222'}}
[2023-02-19 18:10:47.483958] INFO: interface_case_run: 输入参数:url:/openapi/api,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:POST
[2023-02-19 18:10:47.484095] INFO: interface_case_run: 输入参数:url:/openapi/api,key:dfeb1cc8125943d29764a2f2f5c33739,参数:{'password':'1222'},请求方式:None
[2023-02-19 18:10:47.527872] INFO: interface_case_run: 返回结果:{'code': 0, 'result': {'code': 40007, 'text': '您的请求内容为空。'}}
[2023-02-19 18:10:47.528236] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-19 18:10:47.528482] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-19 18:10:47.528716] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=40002'}
[2023-02-19 18:10:47.528998] INFO: interface_case_run: 测试用例执行完毕

+ 44
- 0
log/interface_case_run-2023_02_28_15.log View File

@@ -0,0 +1,44 @@
[2023-02-28 15:45:50.574267] INFO: interface_case_run: 当前模块 解析测试用例文件
[2023-02-28 15:45:50.577260] INFO: interface_case_run: 全部args参数参数信息 , ('E:\\zq\\project\\liwanlei\\jiekou-python3\\test_case_data\\case.xlsx',)
[2023-02-28 15:45:50.578256] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-28 15:45:50.617180] INFO: interface_case_run: 当前模块 解析测试用例文件
[2023-02-28 15:45:50.619180] INFO: interface_case_run: 全部args参数参数信息 , ('E:\\zq\\project\\liwanlei\\jiekou-python3\\test_case_data\\case.xlsx',)
[2023-02-28 15:45:50.623139] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-28 15:45:50.631140] INFO: interface_case_run: 当前模块 测试
[2023-02-28 15:45:50.633135] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.635128] INFO: interface_case_run: 全部kwargs参数信息 , {}
[2023-02-28 15:45:50.658045] INFO: interface_case_run: inputdata> 参数:{"password":"1222"}, url:/ ,返回:{'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}},预期:code=400
[2023-02-28 15:45:50.660072] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-28 15:45:50.662033] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.664060] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=400', 'returnjson': {'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}}}
[2023-02-28 15:45:50.666055] INFO: interface_case_run: 失败重试中
[2023-02-28 15:45:50.676990] INFO: interface_case_run: inputdata> 参数:{"password":"1222"}, url:/ ,返回:{'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}},预期:code=400
[2023-02-28 15:45:50.679987] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-28 15:45:50.681981] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.683976] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=400', 'returnjson': {'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}}}
[2023-02-28 15:45:50.685968] INFO: interface_case_run: 失败重试中
[2023-02-28 15:45:50.694946] INFO: interface_case_run: inputdata> 参数:{"password":"1222"}, url:/ ,返回:{'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}},预期:code=400
[2023-02-28 15:45:50.696968] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-28 15:45:50.698963] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.700926] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=400', 'returnjson': {'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}}}
[2023-02-28 15:45:50.702924] INFO: interface_case_run: 失败重试中次数用完,最后结果
[2023-02-28 15:45:50.713897] INFO: interface_case_run: inputdata> 参数:{"password":"1222"}, url:/ ,返回:{'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}},预期:code=400
[2023-02-28 15:45:50.716886] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-28 15:45:50.718882] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.721871] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=400', 'returnjson': {'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}}}
[2023-02-28 15:45:50.723900] INFO: interface_case_run: 失败重试中
[2023-02-28 15:45:50.731844] INFO: interface_case_run: inputdata> 参数:{"password":"1222"}, url:/ ,返回:{'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}},预期:code=400
[2023-02-28 15:45:50.733862] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-28 15:45:50.735865] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.737826] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=400', 'returnjson': {'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}}}
[2023-02-28 15:45:50.739853] INFO: interface_case_run: 失败重试中
[2023-02-28 15:45:50.748798] INFO: interface_case_run: inputdata> 参数:{"password":"1222"}, url:/ ,返回:{'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}},预期:code=400
[2023-02-28 15:45:50.750793] INFO: interface_case_run: 当前模块 断言测试结果
[2023-02-28 15:45:50.752813] INFO: interface_case_run: 全部args参数参数信息 , ()
[2023-02-28 15:45:50.754784] INFO: interface_case_run: 全部kwargs参数信息 , {'asserassert': 'code=400', 'returnjson': {'code': 0, 'result': {'code': '400', 'msg': 'success', 'data': '123123'}}}
[2023-02-28 15:45:50.756776] INFO: interface_case_run: 失败重试中次数用完,最后结果
[2023-02-28 15:45:50.767752] INFO: interface_case_run: 失败重试中
[2023-02-28 15:45:50.784705] INFO: interface_case_run: 失败重试中次数用完,最后结果
[2023-02-28 15:45:50.787698] INFO: interface_case_run: 当前模块 保存测试结果
[2023-02-28 15:45:50.789692] INFO: interface_case_run: 全部args参数参数信息 , (datetime.datetime(2023, 2, 28, 15, 45, 50, 617180), 3, 0, 2)
[2023-02-28 15:45:50.791719] INFO: interface_case_run: 全部kwargs参数信息 , {}

+ 27
- 0
result.txt View File

@@ -0,0 +1,27 @@
记录测试时间,测试总数,pass数量,失败数量 用‘=’拼接
2017-10-16 20:54:56.323951=3=3=0
2020-11-22 11:19:17.653613=2=0=2
2020-11-22 11:19:55.276935=2=0=2
2020-11-22 11:20:03.408231=2=0=2
2020-11-22 11:20:22.107504=2=0=2
2022-01-15 13:37:10.453363=2=0=2
2022-01-15 13:37:53.945016=2=0=2
2022-01-15 13:38:07.907832=2=0=2
2022-01-15 13:38:16.052044=2=0=2
2022-01-15 13:39:41.019636=2=0=2
2022-01-15 13:39:51.378087=2=0=2
2022-01-15 13:40:33.036679=2=0=2
2022-04-22 17:22:26.808171=2=0=2
2023-02-19 18:06:12.486185=2=0=2
2023-02-19 18:06:17.821946=2=0=2
2023-02-28 15:12:05.803270=3=0=0
2023-02-28 15:16:10.287783=3=0=0
2023-02-28 15:16:49.591922=3=0=0
2023-02-28 15:17:30.399087=3=0=0
2023-02-28 15:19:47.649372=3=0=0
2023-02-28 15:22:16.319412=3=0=0
2023-02-28 15:24:43.906041=3=0=0
2023-02-28 15:33:12.201676=3=0=2
2023-02-28 15:34:42.006208=3=0=1
2023-02-28 15:43:50.790958=3=0=2
2023-02-28 15:45:50.617180=3=0=2

+ 38
- 0
run_excel_re.py View File

@@ -0,0 +1,38 @@
# encoding: utf-8
"""
@author: lileilei
@file: run_excel_re.py
@time: 2017/6/9 12:45
"""
from Public.pyreport_excel import create
import os, threading, datetime
from testCase.case import testinterface
from Public.get_excel import datacel
from Public.create_report import save_result


def start():
starttime = datetime.datetime.now()
mtime = datetime.datetime.now().strftime("%Y%m%d")
basdir = os.path.abspath(os.path.dirname(__file__))

path = os.path.join(os.path.join(os.getcwd(), 'test_case_data'), 'case.xlsx')
listid, listkey, listconeent, listurl, listmethod, listqiwang, listname = datacel(path)
listrelust, list_fail, list_pass, list_json, list_weizhi, listone = testinterface()
filepath = os.path.join(os.path.join(basdir, 'test_Report'), '%s-result.xls' % mtime)
if os.path.exists(filepath) is False:
os.system(r'touch %s' % filepath)
save_result(starttime, len(listrelust), ((list_pass)), list_fail)
create(filename=filepath, list_fail=list_fail, list_pass=list_pass, list_json=list_json, listurls=listurl,
listkeys=listkey, listconeents=listconeent, listfangshis=listmethod,
listqiwangs=listqiwang,
listids=listid, listrelust=listrelust, listnames=listname)


def teThread():
m = threading.Thread(target=start, args=())
m.run()


if __name__ == '__main__':
teThread()

+ 36
- 0
run_html.py View File

@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# @Author : leizi
import os, datetime, time
from testCase.case import testinterface
from Public.py_Html import createHtml
from Public.get_excel import datacel
from Public.create_report import save_result
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')
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)
if os.path.exists(filepath) is False:
os.system(r'touch %s' % filepath)
save_result(starttime, len(listrelust), ((list_pass)), list_fail)
endtime = datetime.datetime.now()
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)
# sendemali(filepath)


def tThread():
m = threading.Thread(target=stast, args=())
m.run()


if __name__ == '__main__':
tThread()

+ 38
- 0
run_http_html.py View File

@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
# @Author : leizi
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')
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)
if os.path.exists(filepath) is False:
os.system(r'touch %s' % filepath)
endtime = datetime.datetime.now()
createHtml(titles=u'http接口自动化测试报告', 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, 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)


if __name__ == '__main__':

start_interface_html_http()

+ 27
- 0
run_new.py View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# @Author : leizi
from testCase.ddt_case import MyTest
import unittest, time, os
from public import BSTestRunner

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()))
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)
besautiful.run(suite)

+ 0
- 0
testCase/__init__.py View File


+ 86
- 0
testCase/case.py View File

@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-
# @Time : 2017/6/4 20:15
# @Author : lileilei
# @File : case.py
from Interface.testFengzhuang import TestApi
from Public.get_excel import datacel
from Public.log import LOG, logger
import os
from config.config import Config_Try_Num, TestPlanUrl

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


@logger('测试')
def testinterface():
list_pass = 0
list_fail = 0
list_json = []
listrelust = []
list_weizhi = 0
list_exption = 0
error_num = 0
for i in range(len(listurl)):
while error_num <= Config_Try_Num + 1:
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]))
assert_re = assert_in(asserassert=listqiwang[i], returnjson=apijson)
if assert_re['code'] == 0:
list_json.append(apijson['result'])
listrelust.append('pass')
list_pass += 1
error_num = 0
continue
elif assert_re['code'] == 1:
if error_num <= Config_Try_Num:
error_num += 1
LOG.info('失败重试中')
else:
LOG.info('失败重试中次数用完,最后结果')
error_num = 0
list_fail += 1
listrelust.append('fail')
list_json.append(apijson['result'])
break
elif assert_re['code'] == 2:
if error_num < Config_Try_Num:
error_num += 1
LOG.info('失败重试中')
else:
LOG.info('失败重试中次数用完,最后结果')
error_num = 0
list_exption += 1
listrelust.append('exception')
list_json.append(assert_re['result'])
break
else:
if error_num < Config_Try_Num:
error_num += 1
LOG.info('失败重试中')
else:
LOG.info('失败重试中次数用完,最后结果')
error_num = 0
list_weizhi += 1
listrelust.append('未知错误')
list_json.append('未知错误')
break
else:
if error_num < Config_Try_Num:
error_num += 1
LOG.info('失败重试中')
else:
LOG.info('失败重试中次数用完,最后结果')
error_num = 0
list_exption += 1
listrelust.append('exception')
list_json.append(apijson['result'])
break
return listrelust, list_fail, list_pass, list_json, list_exption, list_weizhi

+ 79
- 0
testCase/ddt_case.py View File

@@ -0,0 +1,79 @@
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
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):
def setUp(self):
LOG.info('测试用例开始执行')

def tearDown(self):
LOG.info('测试用例执行完毕')

@ddt.data(*data_test)
def test_api(self, data_test):
'''
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="参数格式不对")
LOG.info(parem)
api = TestApi(url=TestPlanUrl + data_test['url'],
parame=parem,
method=data_test['method'])
LOG.info('输入参数:url:%s,key:%s,参数:%s,请求方式:%s' % (data_test['url'], data_test['key'], data_test['assertconnect'],
LOG.info('输入参数:url:%s,key:%s,参数:%s,请求方式:%s' % (
data_test['url'], data_test['key'], data_test['assertconnect'],
data_test['method']))))
apijson = api.getJson()
reslut = {}
reslut[data_test['id']] = apijson
write(reslut)
LOG.info('返回结果:%s' % apijson)
assertall = assertre(asserassert=data_test['assertconnect'])
self.assertNotEqual(dict(assertall), dict(apijson), msg='预期和返回不一致')

+ 52
- 0
testCase/dubbocase.py View File

@@ -0,0 +1,52 @@
"""
@author: lileilei
@file: dubbocase.py
@time: 2018/3/29 12:47
"""
from Interface.dubbo_feng import DubboInterface
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')
listid, listurl, listinterface, listmeth, listfobject, listparam, listassert = datacel(path)


@logger('dubbo接口测试')
def testdubbointerface():
list_pass = 0
list_fail = 0
list_json = []
listrelust = []
list_weizhi = 0
list_exption = 0
for i in range(len(listid)):
dubboapi = DubboInterface(url=listurl, interface=listinterface[i], method=listmeth[i], param=listfobject[i],
**(eval(listparam[i])))
dubboapireslu = dubboapi.getresult()
if dubboapireslu['code'] == 0:
LOG.info('inputdata> 参数:%s, url:%s ,返回:%s,预期:%s' % (listparam[i], listurl[i], dubboapireslu, listassert[i]))
assert_re = assert_in(asserassert=listassert[i], returnjson=dubboapireslu)
if assert_re['code'] == 0:
list_json.append(dubboapireslu['result'])
listrelust.append('pass')
list_pass += 1
elif assert_re['code'] == 1:
list_fail += 1
listrelust.append('fail')
list_json.append(dubboapireslu['result'])
elif assert_re['code'] == 2:
list_exption += 1
listrelust.append('exception')
list_json.append(assert_re['result'])
else:
list_weizhi += 1
listrelust.append('未知错误')
list_json.append('未知错误')
else:
list_exption += 1
listrelust.append('exception')
list_json.append(dubboapireslu['result'])
continue
return listrelust, list_fail, list_pass, list_json, list_exption, list_weizhi

+ 64
- 0
testCase/pytestCasetest.py View File

@@ -0,0 +1,64 @@
'''
@Description
@auther leizi
'''
from Interface.testFengzhuang import TestApi
from public.log import LOG
from public.panduan import assertre
from config.config import TestPlanUrl
import pytest
import os
import yaml
from public.get_excel import makedata
file_dir = os.path.join(os.getcwd(), 'test_Report')
file_reslut = os.path.join(file_dir, 'caseresult.yaml')

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]

data_test = makedata()
@pytest.mark.parametrize(data_test)
class TestParametrize(object):
def test_parame(self):
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:
assert False
get_value = reslut[reply_key_key]
if get_value is None:
assert False
parem_dict[key] = get_value
except Exception as e:
LOG.info("用例依赖执行失败:" + str(e))
assert False
parem.update({'info': parem_dict})
except:
assert False

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']))))
apijson = api.getJson()
reslut = {}
reslut[data_test['id']] = apijson
LOG.info('返回结果:%s' % apijson)
assertall = assertre(asserassert=data_test['qiwang'])

assert dict(assertall) == dict(apijson)

+ 264
- 0
test_Report/2023-0219.html View File

@@ -0,0 +1,264 @@
<!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="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/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> 2023-02-19 18:10:47</p>
<p><strong>持续时间:</strong> 0:00:00.099009</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: 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: 1.处理参数</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>&nbsp;</td>
</tr>
</tfoot>
</table>

<div id='ending'>&nbsp;</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_04_22_21_06_05', '2022_01_16_09_43_50', '2023_02_19_18_10_30', '2022_04_22_21_22_01', '2022_04_22_21_29_08', '2022_01_16_09_43_56', '2022_01_16_09_41_37', '2022_04_22_17_22_51', '2022_01_16_09_39_12', '2022_01_15_14_26_21', '2023_02_19_18_10_47', '2022_01_16_09_41_00', '2022_01_16_09_39_32', '2022_01_16_09_44_26', '2022_04_22_21_32_40', '2022_01_16_09_46_33', '2022_01_16_09_43_15', '2023_02_19_18_06_29', '2023_02_19_18_08_39', '2022_01_16_09_44_35', '2022_01_16_09_45_12', '2022_01_16_09_39_51', '2022_01_16_09_42_37', '2022_01_16_09_38_16', '2022_01_16_09_36_13']
},
yAxis: {
type: 'value'
},
series: [
{
name: '成功',
type: 'line',
stack: '总量',
data: ['2', '2', '2', '2', '2', '2', '2', '2', '0', '2', '2', '0', '0', '2', '2', '2', '2', '2', '2', '2', '2', '0', '2', '0', '0']
},
{
name: '失败',
type: 'line',
stack: '总量',
data: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
},
{
name: '错误',
type: 'line',
stack: '总量',
data: ['0', '0', '0', '0', '0', '0', '0', '0', '2', '0', '0', '2', '2', '0', '0', '0', '0', '0', '0', '0', '0', '2', '0', '2', '2']
}

]
};
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,'&amp;');
s = s.replace(/</g,'&lt;');
s = s.replace(/>/g,'&gt;');
return s;
}
</script>
</body>
</html>

BIN
test_Report/20230219-result.xls View File


+ 117
- 0
test_Report/202302191806-result.html View File

@@ -0,0 +1,117 @@
<!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> 2023-02-19 18:06:22.576639</td>
</tr>
<td><strong>结束时间:</strong> 2023-02-19 18:06:23.111143</td></tr>
<td><strong>耗时:</strong> 0:00:00.534504</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&nbsp;</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>

BIN
test_Report/20230228-result.xls View File


+ 10
- 0
test_Report/caseresult.yaml View File

@@ -0,0 +1,10 @@
1.0:
code: 0
result:
code: 40007
text: 您的请求内容为空。
2.0:
code: 0
result:
code: 40007
text: 您的请求内容为空。

BIN
test_case_data/case.xlsx View File


BIN
test_case_data/dubbocase.xlsx View File


+ 38
- 0
yesy View File

@@ -0,0 +1,38 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAsbthKV/+8Yu5V2R2quG1Xy6kvkZ6PcRzSoarxXh6zxoxVlyEZNXP
09a9jdf1fS2l9KRaimxjr94mH4r8JGL6afyegKwPJCyjeXrjsFJMpyn4YAOs5qTMO34WbO
88BSc53omDWuPvQaQFPpMK5rAs4E5c2o91tkzRks52+B2Y1wkIYFZYDBHugVgiY7B6PHQi
RGoMKbuM5gvxU1zGvGumvUoUo0lXs8oLFtHpp2jZypJdlgRRGfVzfw+bD3LrfH7J6+Lse5
bZEsNB+xxRO2qQMb/2fOiP0fRXZRWX+PTkvpqNxxub7Fil8XjUY0M2W0/DG8wPAMfPxt8B
ZY9ciLL+vsNobPDzsHgOxbD0+nc4XVou+RdMaAmxs8a95BGVsi0236laA/pHcMcyarCGja
wJrZK+yBe+79NU45umMB9uXn7CY4j4oUX5izTHu+l9tiqpRYsmegcQMSBgDvPd/Q58kgIb
WybvdOUM9OMfYeWfUXyvT84BOVVNXGGqdKrIWycDAAAFkLHO9WWxzvVlAAAAB3NzaC1yc2
EAAAGBALG7YSlf/vGLuVdkdqrhtV8upL5Gej3Ec0qGq8V4es8aMVZchGTVz9PWvY3X9X0t
pfSkWopsY6/eJh+K/CRi+mn8noCsDyQso3l647BSTKcp+GADrOakzDt+FmzvPAUnOd6Jg1
rj70GkBT6TCuawLOBOXNqPdbZM0ZLOdvgdmNcJCGBWWAwR7oFYImOwejx0IkRqDCm7jOYL
8VNcxrxrpr1KFKNJV7PKCxbR6ado2cqSXZYEURn1c38Pmw9y63x+yevi7HuW2RLDQfscUT
tqkDG/9nzoj9H0V2UVl/j05L6ajccbm+xYpfF41GNDNltPwxvMDwDHz8bfAWWPXIiy/r7D
aGzw87B4DsWw9Pp3OF1aLvkXTGgJsbPGveQRlbItNt+pWgP6R3DHMmqwho2sCa2SvsgXvu
/TVOObpjAfbl5+wmOI+KFF+Ys0x7vpfbYqqUWLJnoHEDEgYA7z3f0OfJICG1sm73TlDPTj
H2Hln1F8r0/OATlVTVxhqnSqyFsnAwAAAAMBAAEAAAGAQoE2IzBLioDZEo2CJgEdSAeBF7
3xgelfprRr1BF4CsTnT0SBOeYTxVXmSgxUTMnm/nr9ciyKxMUgiM8N+GOdBknD2awIYmXd
qdhFGLZC/o4i5XKaoRdrYJuWsp52XAtIiS/1me4OmgZQ/BAzlQy5ThmkfxgNWPC3vvJI7C
DPDy/PFZVZjvKqx3V+MMVZiAOAyw7PjFIkr/QqEiJ2Lw0tMElnHY6VJa5lpd1YTA9c54ML
R9ZHrqn81L+3Kvm6ijQ6o+8k/qZ9vtDBCm062iMnL7bYlZPHAAwcmTA1j781yZVzCiw8BT
6/qSc4nxq7UROks/pd8MrG+a8W/N5L+/2sP5ovWMqRMZDGG+qTwV7DHk001JKhwDzYOtHh
rqmXyJpEUCtSpTNW8fuhfsbJisVyD5+VYECrPclCetPMwP5cXf5Lf/7cV4nOFo3jJkoDF7
rwDjgNC/VF/n1qAz4vw5Lp8ijj7z+uP4SPOpDYxDl8lTcXntDvf4HRarRYX59WUSChAAAA
wQDWvVI9iAwme/0r/iJWoM79wlcNc+YK1i7TNlI41v720fAFKu/9AQat4dmosoPn10d+EE
Vd83A4YTh3xsMGErxBxTl8twNFHcZsB1o9uO8rkTQOoRyJrDu1X8YKxav+p0IEbxeFsZyq
JlPESgY19ZBMsrPyQTChowmYoGIljtspJzHcc6qrTm56vxgXnWbBHKQ5VXdlxFABAsH3d5
51dvQquQR98q348B5TD7IaEEkQRmgqYQFwwa0ApAVXgFBBP00AAADBAOyQ02MNWLdxyI66
V8F6VvTppo+DdT9N7GCZBxPQs/vZ8KcaXRGDvbW8/fLB83UH6pA3MZ8bQ5XJ7vNBsyOSgw
xevFEpwz5KCxwj9JYP534tjtn89QH7tgsAjnETnrDePisUOpKVDdLm8yIhMp1/LJ5/kJj9
J3MaxEQYSlhiBmEeUl9f/JMYx9c20zp4jRAO3d2o9NOzfswgvOCqhfQ7y1xYUcNXeKjP3i
k9nQLgZVWXBsq6cIPYq/P7l0AuxG/4swAAAMEAwFU7A89t6FCmr45WjwPYinkWVHe1+Ok+
MEVAW3YfPEsVPf5nb/Uvo2q6Qr8OjzqPIWS4WiPOpzYdkI2abBfo/f/sn3VzXBnpbo/wOP
NHgdWPs/X1HXmohnBEAjmkGFjjvS2BZhRZ6YMimk5fOkB1qHjQ9r4FuwmiAOBdo/Mstl94
1ZZPgzARnqeS8HB0sl0lY8+pYGbGyxxBpAR5/uC6PR5XBYUPD52leir92FTby1u6JGIIhn
R9HaLEgR8YyCBxAAAAE2xlaWxlaWxpMTI2QDE2My5jb20BAgMEBQYH
-----END OPENSSH PRIVATE KEY-----

+ 1
- 0
yesy.pub View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxu2EpX/7xi7lXZHaq4bVfLqS+Rno9xHNKhqvFeHrPGjFWXIRk1c/T1r2N1/V9LaX0pFqKbGOv3iYfivwkYvpp/J6ArA8kLKN5euOwUkynKfhgA6zmpMw7fhZs7zwFJzneiYNa4+9BpAU+kwrmsCzgTlzaj3W2TNGSznb4HZjXCQhgVlgMEe6BWCJjsHo8dCJEagwpu4zmC/FTXMa8a6a9ShSjSVezygsW0emnaNnKkl2WBFEZ9XN/D5sPcut8fsnr4ux7ltkSw0H7HFE7apAxv/Z86I/R9FdlFZf49OS+mo3HG5vsWKXxeNRjQzZbT8MbzA8Ax8/G3wFlj1yIsv6+w2hs8POweA7FsPT6dzhdWi75F0xoCbGzxr3kEZWyLTbfqVoD+kdwxzJqsIaNrAmtkr7IF77v01Tjm6YwH25efsJjiPihRfmLNMe76X22KqlFiyZ6BxAxIGAO8939DnySAhtbJu905Qz04x9h5Z9RfK9PzgE5VU1cYap0qshbJwM= leileili126@163.com

Loading…
Cancel
Save