At Aug 2 A.
This commit is contained in:
parent
4c27db832a
commit
583a82fb03
|
@ -229,7 +229,7 @@
|
|||
series: [{
|
||||
name: '通过',
|
||||
color: '#64bb64',
|
||||
data: [1]
|
||||
data: [4]
|
||||
}, {
|
||||
name: '失败',
|
||||
color: '#f16d7e',
|
||||
|
@ -237,7 +237,7 @@
|
|||
}, {
|
||||
name: '错误',
|
||||
color: '#fdc68c',
|
||||
data: [2]
|
||||
data: [0]
|
||||
}]
|
||||
})
|
||||
// 增加饼状图
|
||||
|
@ -291,7 +291,7 @@
|
|||
innerSize: '80%',
|
||||
name: '比例',
|
||||
data: [
|
||||
['通过', 1], ['失败', 0], ['错误', 2]
|
||||
['通过', 4], ['失败', 0], ['错误', 0]
|
||||
]
|
||||
}]
|
||||
}, function(c) {
|
||||
|
@ -438,15 +438,15 @@ function html_escape(s) {
|
|||
<div id="testinfo" style="max-width: 360px; width: auto; float: left;">
|
||||
<h1 style="margin: 5px 0px 10px 0px; font-family: Microsoft YaHei;">测试报告</h1>
|
||||
|
||||
<p class='attribute'><strong>开始时间 : </strong> 2022-08-01 01:43:42</p>
|
||||
<p class='attribute'><strong>开始时间 : </strong> 2022-08-02 03:42:02</p>
|
||||
|
||||
<p class='attribute'><strong>合计耗时 : </strong> 00:00:01</p>
|
||||
<p class='attribute'><strong>合计耗时 : </strong> 00:00:00</p>
|
||||
|
||||
<p class='attribute'><strong>测试结果 : </strong> 总共 3,通过 1,失败 0,错误 2,通过率 33.33%</p>
|
||||
<p class='attribute'><strong>测试结果 : </strong> 总共 4,通过 4,失败 0,错误 0,通过率 100.00%</p>
|
||||
|
||||
<p class='attribute'><strong>失败用例 : </strong> 无</p>
|
||||
|
||||
<p class='attribute'><strong>错误用例 : </strong> <a class='showDetail' data-toggle='collapse' href='#errorsCaseOl' style='text-decoration: none;'>点击查看</a><ol id='errorsCaseOl' class='collapse' style='float: left; font-family: Menlo,Monaco,Consolas,monospace;'><li>main.测试用例.test0002_None</li><li>main.测试用例.test0003_None</li></ol></p>
|
||||
<p class='attribute'><strong>错误用例 : </strong> 无</p>
|
||||
|
||||
<p class='description'></p>
|
||||
</div>
|
||||
|
@ -457,11 +457,11 @@ function html_escape(s) {
|
|||
|
||||
<div style="width: auto; clear: both;">
|
||||
<p id='show_detail_line'>
|
||||
<a class="btn btn-primary" href='javascript:showCase(0)'>概要 33.33%</a>
|
||||
<a class="btn btn-success" href='javascript:showCase(2)'>通过 1</a>
|
||||
<a class="btn btn-primary" href='javascript:showCase(0)'>概要 100.00%</a>
|
||||
<a class="btn btn-success" href='javascript:showCase(2)'>通过 4</a>
|
||||
<a class="btn btn-danger" href='javascript:showCase(1)'>失败 0</a>
|
||||
<a class="btn btn-warning" href='javascript:showCase(3)'>错误 2</a>
|
||||
<a class="btn btn-info" href='javascript:showCase(4)'>全部 3</a>
|
||||
<a class="btn btn-warning" href='javascript:showCase(3)'>错误 0</a>
|
||||
<a class="btn btn-info" href='javascript:showCase(4)'>全部 4</a>
|
||||
</p>
|
||||
</div>
|
||||
<table id='result_table' class="table table-condensed table-bordered table-hover">
|
||||
|
@ -486,160 +486,180 @@ function html_escape(s) {
|
|||
<td>详细</td>
|
||||
</tr>
|
||||
|
||||
<tr class='errorClass warning'>
|
||||
<tr class='passClass warning'>
|
||||
<td>测试用例</td>
|
||||
<td></td>
|
||||
<td class="text-center">3</td>
|
||||
<td class="text-center">1</td>
|
||||
<td class="text-center">4</td>
|
||||
<td class="text-center">4</td>
|
||||
<td class="text-center">0</td>
|
||||
<td class="text-center">2</td>
|
||||
<td class="text-center">1.258秒</td>
|
||||
<td class="text-center"><a href="javascript:showClassDetail('c1',3)" class="detail" id='c1'>查看全部</a></td>
|
||||
<td class="text-center">0</td>
|
||||
<td class="text-center">0.890秒</td>
|
||||
<td class="text-center"><a href="javascript:showClassDetail('c1',4)" class="detail" id='c1'>查看全部</a></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1_1' class='hiddenRow'>
|
||||
<td class='passedCase' style="vertical-align: middle"><div class='testcase'>test0001_TestLogin</div></td>
|
||||
<td style="vertical-align: middle">正常登录</td>
|
||||
<td class='passedCase' style="vertical-align: middle"><div class='testcase'>test0001_1</div></td>
|
||||
<td style="vertical-align: middle"></td>
|
||||
<td colspan='5' align='center'>
|
||||
<button id='btn_pt1_1' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_pt1_1'>通过</button>
|
||||
<div id='div_pt1_1' class="collapse in">
|
||||
<pre style="text-align:left;font-size:12px;color:#282828">pt1_1:
|
||||
2022-08-01 01:43:42,869 - D: 正在执行:正常登录
|
||||
2022-08-01 01:43:44,092 - D:
|
||||
2022-08-02 03:42:02,491 - D: 正在执行:None
|
||||
2022-08-02 03:42:02,765 - D:
|
||||
[->]
|
||||
POST /filebox.php?op=home HTTP/1.1
|
||||
GET /iplookup?type=json&ip=61.139.2.69 HTTP/1.1
|
||||
Host: www.fanscloud.net
|
||||
User-Agent: curl
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
|
||||
Accept-Encoding: gzip, deflate
|
||||
Accept: */*
|
||||
Connection: keep-alive
|
||||
Content-Length: 59
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
X-Online-Host: 127.0.0.1
|
||||
|
||||
|
||||
user=&pass=1234ABCDabcd&submitButtonName=%E7%99%BB%E5%BD%95
|
||||
[<-]
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx
|
||||
Date: Sun, 31 Jul 2022 17:43:44 GMT
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Date: Mon, 01 Aug 2022 19:42:02 GMT
|
||||
Content-Type: application/json; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Vary: Accept-Encoding
|
||||
Set-Cookie: PHPSESSID=b9lvik70qp9ejqt0gtguv2evn4; path=/, user=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0, pass=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
|
||||
Expires: Thu, 19 Nov 1981 08:52:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Pragma: no-cache
|
||||
Content-Encoding: gzip
|
||||
|
||||
<!DOCTYPE html>
|
||||
<meta name='robots' content='noindex,follow' />
|
||||
<head>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'/>
|
||||
<title>www.fanscloud.net - 登录</title>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
*{font-family:'Consolas';}.box{border:1px solid #ccc;b ... [MORE 94% OMITTED HERE]
|
||||
{
|
||||
"status": 0,
|
||||
"ip": "61.139.2.69",
|
||||
"location": "\u56db\u5ddd\u7701\u6210\u90fd\u5e02",
|
||||
"isp": "\u7535\u4fe1",
|
||||
"ttl": 196140
|
||||
}
|
||||
</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td class='passedCase' style="vertical-align: middle"></td>
|
||||
</tr>
|
||||
|
||||
<tr id='et1_2' class='none'>
|
||||
<td class='errorsCase' style="vertical-align: middle"><div class='testcase'>test0002_None</div></td>
|
||||
<tr id='pt1_2' class='hiddenRow'>
|
||||
<td class='passedCase' style="vertical-align: middle"><div class='testcase'>test0002_2</div></td>
|
||||
<td style="vertical-align: middle"></td>
|
||||
<td colspan='5' align='center'>
|
||||
<button id='btn_et1_2' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_et1_2'>错误</button>
|
||||
<div id='div_et1_2' class="collapse in">
|
||||
<pre style="text-align:left;font-size:12px;color:#e52000">et1_2:
|
||||
2022-08-01 01:43:44,094 - D: 正在执行:None
|
||||
Traceback (most recent call last):
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexes\base.py", line 3621, in get_loc
|
||||
return self._engine.get_loc(casted_key)
|
||||
File "pandas\_libs\index.pyx", line 136, in pandas._libs.index.IndexEngine.get_loc
|
||||
File "pandas\_libs\index.pyx", line 163, in pandas._libs.index.IndexEngine.get_loc
|
||||
File "pandas\_libs\hashtable_class_helper.pxi", line 2131, in pandas._libs.hashtable.Int64HashTable.get_item
|
||||
File "pandas\_libs\hashtable_class_helper.pxi", line 2140, in pandas._libs.hashtable.Int64HashTable.get_item
|
||||
KeyError: 0
|
||||
<button id='btn_pt1_2' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_pt1_2'>通过</button>
|
||||
<div id='div_pt1_2' class="collapse in">
|
||||
<pre style="text-align:left;font-size:12px;color:#282828">pt1_2:
|
||||
2022-08-02 03:42:02,765 - D: 正在执行:None
|
||||
2022-08-02 03:42:02,960 - D:
|
||||
[->]
|
||||
GET /iplookup?type=xml HTTP/1.1
|
||||
Host: www.fanscloud.net
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
|
||||
Accept-Encoding: gzip, deflate
|
||||
Accept: */*
|
||||
Connection: keep-alive
|
||||
Cookie: user=zhaoyafan
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "D:\Project\AutoFramework\Runner\API\DefaultRunner.py", line 223, in foo
|
||||
def foo(self, index=i): return self._test_(index)
|
||||
File "D:\Project\AutoFramework\Runner\API\DefaultRunner.py", line 211, in test
|
||||
self.test_unit(data=main_case)
|
||||
File "D:\Project\AutoFramework\Runner\API\DefaultRunner.py", line 179, in test_unit
|
||||
HTTPCh = self.h.where((self.h['Env'] == self.envs) & (self.h['Name'] == data['HTTPCh']), inplace=False).dropna(how='all').loc[0].to_dict()
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexing.py", line 967, in __getitem__
|
||||
return self._getitem_axis(maybe_callable, axis=axis)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexing.py", line 1202, in _getitem_axis
|
||||
return self._get_label(key, axis=axis)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexing.py", line 1153, in _get_label
|
||||
return self.obj.xs(label, axis=axis)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\generic.py", line 3864, in xs
|
||||
loc = index.get_loc(key)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexes\base.py", line 3623, in get_loc
|
||||
raise KeyError(key) from err
|
||||
KeyError: 0
|
||||
[<-]
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx
|
||||
Date: Mon, 01 Aug 2022 19:42:02 GMT
|
||||
Content-Type: text/xml; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Vary: Accept-Encoding
|
||||
Content-Encoding: gzip
|
||||
|
||||
<data><status>0</status>
|
||||
<ip>117.136.31.226</ip>
|
||||
<location>广东省</location>
|
||||
<isp>移动</isp>
|
||||
<ttl>2675952</ttl>
|
||||
</data>
|
||||
</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td class='errorsCase' style="vertical-align: middle"></td>
|
||||
<td class='passedCase' style="vertical-align: middle"></td>
|
||||
</tr>
|
||||
|
||||
<tr id='et1_3' class='none'>
|
||||
<td class='errorsCase' style="vertical-align: middle"><div class='testcase'>test0003_None</div></td>
|
||||
<tr id='pt1_3' class='hiddenRow'>
|
||||
<td class='passedCase' style="vertical-align: middle"><div class='testcase'>test0003_3</div></td>
|
||||
<td style="vertical-align: middle"></td>
|
||||
<td colspan='5' align='center'>
|
||||
<button id='btn_et1_3' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_et1_3'>错误</button>
|
||||
<div id='div_et1_3' class="collapse in">
|
||||
<pre style="text-align:left;font-size:12px;color:#e52000">et1_3:
|
||||
2022-08-01 01:43:44,120 - D: 正在执行:None
|
||||
Traceback (most recent call last):
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexes\base.py", line 3621, in get_loc
|
||||
return self._engine.get_loc(casted_key)
|
||||
File "pandas\_libs\index.pyx", line 136, in pandas._libs.index.IndexEngine.get_loc
|
||||
File "pandas\_libs\index.pyx", line 163, in pandas._libs.index.IndexEngine.get_loc
|
||||
File "pandas\_libs\hashtable_class_helper.pxi", line 2131, in pandas._libs.hashtable.Int64HashTable.get_item
|
||||
File "pandas\_libs\hashtable_class_helper.pxi", line 2140, in pandas._libs.hashtable.Int64HashTable.get_item
|
||||
KeyError: 0
|
||||
<button id='btn_pt1_3' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_pt1_3'>通过</button>
|
||||
<div id='div_pt1_3' class="collapse in">
|
||||
<pre style="text-align:left;font-size:12px;color:#282828">pt1_3:
|
||||
2022-08-02 03:42:02,960 - D: 正在执行:None
|
||||
2022-08-02 03:42:03,191 - D:
|
||||
[->]
|
||||
GET /iplookup?ip=61.139.2.69 HTTP/1.1
|
||||
Host: www.fanscloud.net
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
|
||||
Accept-Encoding: gzip, deflate
|
||||
Accept: */*
|
||||
Connection: keep-alive
|
||||
Content-Length: 2706
|
||||
Content-Type: multipart/form-data; boundary=4b57104e32f8f2d3af8fc5c7795bb3fa
|
||||
|
||||
The above exception was the direct cause of the following exception:
|
||||
--4b57104e32f8f2d3af8fc5c7795bb3fa\r\nContent-Disposition: form-data; name="file01"; filename="\xe6\x8e\xa5\xe5\x8f\xa3\xe6\x96\x87\xe6\xa1\xa3.md"\r\n\r\n# \xe6\x8e\xa5\xe5\x8f\xa3\xe6\x96\x87\xe6\xa1\xa3\n\n## \xe6\xb3\xa8\xe5\x86\x8c\xe6\x8e\xa5\xe5\x8f ... [MORE 93% OMITTED HERE]
|
||||
[<-]
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx
|
||||
Date: Mon, 01 Aug 2022 19:42:02 GMT
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Vary: Accept-Encoding
|
||||
Content-Encoding: gzip
|
||||
|
||||
Traceback (most recent call last):
|
||||
File "D:\Project\AutoFramework\Runner\API\DefaultRunner.py", line 223, in foo
|
||||
def foo(self, index=i): return self._test_(index)
|
||||
File "D:\Project\AutoFramework\Runner\API\DefaultRunner.py", line 211, in test
|
||||
self.test_unit(data=main_case)
|
||||
File "D:\Project\AutoFramework\Runner\API\DefaultRunner.py", line 179, in test_unit
|
||||
HTTPCh = self.h.where((self.h['Env'] == self.envs) & (self.h['Name'] == data['HTTPCh']), inplace=False).dropna(how='all').loc[0].to_dict()
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexing.py", line 967, in __getitem__
|
||||
return self._getitem_axis(maybe_callable, axis=axis)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexing.py", line 1202, in _getitem_axis
|
||||
return self._get_label(key, axis=axis)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexing.py", line 1153, in _get_label
|
||||
return self.obj.xs(label, axis=axis)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\generic.py", line 3864, in xs
|
||||
loc = index.get_loc(key)
|
||||
File "D:\Project\AutoFramework\venv\lib\site-packages\pandas\core\indexes\base.py", line 3623, in get_loc
|
||||
raise KeyError(key) from err
|
||||
KeyError: 0
|
||||
61.139.2.69 四川省成都市 电信
|
||||
</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td class='errorsCase' style="vertical-align: middle"></td>
|
||||
<td class='passedCase' style="vertical-align: middle"></td>
|
||||
</tr>
|
||||
|
||||
<tr id='pt1_4' class='hiddenRow'>
|
||||
<td class='passedCase' style="vertical-align: middle"><div class='testcase'>test0004_4</div></td>
|
||||
<td style="vertical-align: middle"></td>
|
||||
<td colspan='5' align='center'>
|
||||
<button id='btn_pt1_4' type="button" class="btn btn-xs" data-toggle="collapse" data-target='#div_pt1_4'>通过</button>
|
||||
<div id='div_pt1_4' class="collapse in">
|
||||
<pre style="text-align:left;font-size:12px;color:#282828">pt1_4:
|
||||
2022-08-02 03:42:03,191 - D: 正在执行:None
|
||||
2022-08-02 03:42:03,382 - D:
|
||||
[->]
|
||||
GET /iplookup HTTP/1.1
|
||||
Host: www.fanscloud.net
|
||||
User-Agent: curl/7.0
|
||||
Accept-Encoding: gzip, deflate
|
||||
Accept: */*
|
||||
Connection: keep-alive
|
||||
Cookie: user=zhaoyafan
|
||||
|
||||
|
||||
[<-]
|
||||
HTTP/1.1 200 OK
|
||||
Server: nginx
|
||||
Date: Mon, 01 Aug 2022 19:42:02 GMT
|
||||
Content-Type: text/html; charset=utf-8
|
||||
Transfer-Encoding: chunked
|
||||
Connection: keep-alive
|
||||
Vary: Accept-Encoding
|
||||
Content-Encoding: gzip
|
||||
|
||||
117.136.31.226 广东省 移动
|
||||
|
||||
</pre>
|
||||
</div>
|
||||
</td>
|
||||
<td class='passedCase' style="vertical-align: middle"></td>
|
||||
</tr>
|
||||
|
||||
<tr id='total_row' class="text-center active">
|
||||
<td colspan='2'>总计</td>
|
||||
<td>3</td>
|
||||
<td>1</td>
|
||||
<td>4</td>
|
||||
<td>4</td>
|
||||
<td>0</td>
|
||||
<td>2</td>
|
||||
<td>1.258秒</td>
|
||||
<td>通过:33.33%</td>
|
||||
<td>0</td>
|
||||
<td>0.890秒</td>
|
||||
<td>通过:100.00%</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
|
|
@ -1,69 +1,123 @@
|
|||
import unittest
|
||||
from typing import Any, Text, Dict, List
|
||||
from Business.Class.HTMLTestRunner import HTMLTestRunner
|
||||
from Business.Class.ExcelUtils import *
|
||||
from Business.Class.JsonOrYaml import *
|
||||
from Base.Class.Http import *
|
||||
from Base.Class.Database import *
|
||||
from Base.Class.Logger import *
|
||||
|
||||
log = Logger(name='test', level='DEBUG')
|
||||
|
||||
|
||||
class TestCase:
|
||||
_g = {}
|
||||
_l = {}
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
workbook,
|
||||
envs,
|
||||
level_list: list = None,
|
||||
workbook_config: dict = None,
|
||||
testcase: str = None,
|
||||
testdata: str = None,
|
||||
database: str = None,
|
||||
httpconf: str = None
|
||||
workbook: Text,
|
||||
testlves: List,
|
||||
testcase: Text,
|
||||
testdata: Text,
|
||||
database: Text,
|
||||
httpconf: Text
|
||||
):
|
||||
if workbook_config is None: workbook_config = {}
|
||||
tabs = self._merge_dict(
|
||||
{
|
||||
'HTTPConf': {
|
||||
'sheet': httpconf
|
||||
tabs = {
|
||||
"HTTPConf": {
|
||||
"fixed": {},
|
||||
"views": "A4:C*",
|
||||
"field": [
|
||||
"Name",
|
||||
"HostWithScheme",
|
||||
"DefaultHeader"
|
||||
]
|
||||
},
|
||||
"DataBase": {
|
||||
"fixed": {},
|
||||
"views": "E4:L*",
|
||||
"field": [
|
||||
"Name",
|
||||
"Type",
|
||||
"Host",
|
||||
"Port",
|
||||
"User",
|
||||
"Password",
|
||||
"Database",
|
||||
"Charset"
|
||||
]
|
||||
},
|
||||
"TestData": {
|
||||
"fixed": {},
|
||||
"views": "A4:E*",
|
||||
"field": [
|
||||
"Name",
|
||||
"Delimiter",
|
||||
"Data",
|
||||
"FileData",
|
||||
"VarNameList"
|
||||
]
|
||||
},
|
||||
"TestCase": {
|
||||
"fixed": {
|
||||
"ItemName": "B3",
|
||||
"SessMode": "E3"
|
||||
},
|
||||
'DataBase': {
|
||||
'sheet': database
|
||||
},
|
||||
'TestData': {
|
||||
'sheet': testdata
|
||||
},
|
||||
'TestCase': {
|
||||
'sheet': testcase
|
||||
}
|
||||
"views": "A7:AG*",
|
||||
"field": [
|
||||
"Flag",
|
||||
"PreExecCase",
|
||||
"PreExecRule",
|
||||
"Module",
|
||||
"CaseId",
|
||||
"CaseTitle",
|
||||
"CaseDesc",
|
||||
"CaseLevel",
|
||||
"HTTPChannel",
|
||||
"HTTPMethod",
|
||||
"HTTPUri",
|
||||
"HTTPQuery",
|
||||
"HTTPRedirect",
|
||||
"HTTPHeaders",
|
||||
"HTTPCookies",
|
||||
"HTTPParamType",
|
||||
"HTTPParamContent",
|
||||
"HTTPParamOfFile",
|
||||
"HTTPExtract",
|
||||
"HTTPAssertStatus",
|
||||
"HTTPAssertHeaders",
|
||||
"HTTPAssertCookies",
|
||||
"HTTPAssertBody",
|
||||
"HTTPAssertJson",
|
||||
"DatabaseCh",
|
||||
"DatabaseSqlQuery",
|
||||
"DatabaseExtract",
|
||||
"DatabaseAssertData",
|
||||
"DatabaseAssertCount",
|
||||
"DataSet",
|
||||
"Author",
|
||||
"TestTime",
|
||||
"TestResult"
|
||||
]
|
||||
}
|
||||
, workbook_config)
|
||||
# tabs = {
|
||||
# 'HTTPConf': {
|
||||
# 'sheet': '数据配置'
|
||||
# },
|
||||
# 'DataBase': {
|
||||
# 'sheet': '数据配置'
|
||||
# },
|
||||
# 'TestData': {
|
||||
# 'sheet': '数据配置'
|
||||
# },
|
||||
# 'TestCase': {
|
||||
# 'sheet': '测试用例'
|
||||
# }
|
||||
# }
|
||||
}
|
||||
import os
|
||||
from pandas.core.frame import DataFrame
|
||||
init = Excel().open(workbook, read_only=True)
|
||||
file = os.path.splitext(workbook)[0] + '.json'
|
||||
conf = self._merge_dict((os.path.exists(file) and auto_decode(open(file, 'r', encoding='utf-8').read())) or {}, tabs)
|
||||
# print(json_encode(conf, indent=4, unicode=False))
|
||||
# exit()
|
||||
data = {}
|
||||
for k, v in conf.items():
|
||||
sheet_name = ('sheet' in v and v['sheet'] or v['default_sheet'])
|
||||
init.select(sheet_name)
|
||||
for k, v in tabs.items():
|
||||
match k:
|
||||
case 'TestCase':
|
||||
sheet = testcase
|
||||
case 'TestData':
|
||||
sheet = testdata
|
||||
case 'DataBase':
|
||||
sheet = database
|
||||
case 'HTTPConf':
|
||||
sheet = httpconf
|
||||
case _:
|
||||
continue
|
||||
init.select(sheet)
|
||||
data[k] = {}
|
||||
if 'fixed' in v.keys():
|
||||
data[k]['fixed'] = {}
|
||||
|
@ -71,13 +125,9 @@ class TestCase:
|
|||
data[k]['fixed'][key] = init.cellGet(cell=value)
|
||||
if 'views' in v.keys() and 'field' in v.keys():
|
||||
data[k]['views'] = DataFrame(read_view_dict(
|
||||
filename=workbook, sheet=sheet_name, area=v['views'], fields=v['field'], auto_truncate=True))
|
||||
filename=workbook, sheet=sheet, area=v['views'], fields=v['field'], auto_truncate=True))
|
||||
else:
|
||||
init.exit()
|
||||
# print(json_encode(data['DataBase'], indent=4, unicode=False))
|
||||
# exit()
|
||||
|
||||
self.envs = envs
|
||||
self.case = testcase
|
||||
self.http = Request
|
||||
self.dirs = os.path.dirname(workbook)
|
||||
|
@ -89,13 +139,11 @@ class TestCase:
|
|||
self.d = data['TestData']['views']
|
||||
self.c = data['TestCase']['views']
|
||||
|
||||
self._setLevels(level_list)
|
||||
self._setLevels(testlves)
|
||||
self._setRequestMode(self.m)
|
||||
|
||||
|
||||
def _setRequestMode(self, value=None):
|
||||
self.http = [Request, Session][value in ['会话模式', 'Session', 'session']]()
|
||||
return True
|
||||
|
||||
def _setLevels(self, level_list=None):
|
||||
if isinstance(level_list, (list, tuple, str)):
|
||||
|
@ -176,34 +224,39 @@ class TestCase:
|
|||
# 开始测试
|
||||
log.d('正在执行:%s' % data['CaseTitle'])
|
||||
# 请求构造
|
||||
HTTPCh = self.h.where((self.h['Env'] == self.envs) & (self.h['Name'] == data['HTTPCh']), inplace=False).dropna(how='all').loc[0].to_dict()
|
||||
locals().setdefault('HTTPChannel', self.h.where((self.h['Name'] == data['HTTPChannel']), inplace=False).dropna(how='all').loc[0].to_dict())
|
||||
resKwArgs = {
|
||||
'debug': True,
|
||||
'method': data['HTTPMethod'],
|
||||
'url': self._sub_variable_auto((HTTPCh['HostWithScheme'] or '') + (data['HTTPUri'] or '/'), [self._g, self._l]),
|
||||
'query': self._sub_variable_auto(auto_decode(data['HTTPQuery']), [self._g, self._l]),
|
||||
'header': self._sub_variable_auto(auto_decode(data['HTTPHeaders']), [self._g, self._l]),
|
||||
'cookie': self._sub_variable_auto(auto_decode(data['HTTPCookies']), [self._g, self._l]),
|
||||
'auto_redirect': data['HTTPRedirect'] in ['是', 'True', 'true']
|
||||
'method': data['HTTPMethod'] or 'GET',
|
||||
'url': self._sub_variable_auto((locals().get('HTTPChannel')['HostWithScheme'] or '') + (data['HTTPUri'] or '/'),
|
||||
[self._g, self._l]),
|
||||
'query': self._sub_variable_auto(auto_decode(data['HTTPQuery']), [self._g, self._l]),
|
||||
'data': None,
|
||||
'data_json': None,
|
||||
'data_file': None,
|
||||
'header': {},
|
||||
'cookie': self._sub_variable_auto(auto_decode(data['HTTPCookies']), [self._g, self._l]),
|
||||
'auth': None,
|
||||
'timeout': 60,
|
||||
'proxy': None,
|
||||
'auto_redirect': data['HTTPRedirect'] in ['是', 'True', 'true'],
|
||||
'ignore_cert_error': False,
|
||||
'debug': True
|
||||
}
|
||||
resKwArgs['header'].update(auto_decode(locals().get('HTTPChannel')['DefaultHeader']) or {})
|
||||
resKwArgs['header'].update(self._sub_variable_auto(auto_decode(data['HTTPHeaders']), [self._g, self._l]) or {})
|
||||
match self._matchParmType(data['HTTPParamType']):
|
||||
case 10:
|
||||
resKwArgs['data_json'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent']))
|
||||
case 20:
|
||||
resKwArgs['data'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent']))
|
||||
resKwArgs['data'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent']))
|
||||
case _:
|
||||
resKwArgs['data'] = self._sub_variable_auto(data['HTTPParamContent'])
|
||||
HTTPParamOfFile = self._sub_variable_auto(auto_decode(data['HTTPParamOfFile']))
|
||||
if isinstance(HTTPParamOfFile, dict):
|
||||
resKwArgs['data_file'] = {k: open(os.path.abspath(os.path.join(self.dirs, './%s' % v)), 'rb') for k, v in HTTPParamOfFile.items()}
|
||||
# for k, v in HTTPParamOfFile:
|
||||
# HTTPParamOfFile[k] = open(os.path.abspath(os.path.join(self.dirs, './%s' % v)), 'rb')
|
||||
# resKwArgs['data_file'] = HTTPParamOfFile
|
||||
resKwArgs['data'] = self._sub_variable_auto(data['HTTPParamContent'])
|
||||
# httpParamOfFile = self._sub_variable_auto(auto_decode(data['HTTPParamOfFile']))
|
||||
resKwArgs['data_file'] = locals().setdefault('httpParamOfFile', self._sub_variable_auto(auto_decode(
|
||||
data['HTTPParamOfFile']))) and {k: open(os.path.abspath(os.path.join(self.dirs, './%s' % v)), 'rb') for k, v in locals().get('httpParamOfFile').items()}
|
||||
|
||||
res = self.http.http(**resKwArgs)
|
||||
log.d('\n%s' % (res['brief'] or ''))
|
||||
# print(res)
|
||||
# print(HTTPCh)
|
||||
|
||||
def test(self, index):
|
||||
# print(view_case.loc[index])
|
||||
|
@ -213,6 +266,7 @@ class TestCase:
|
|||
def main(self):
|
||||
class ClassTestCase(unittest.TestCase):
|
||||
pass
|
||||
|
||||
ClassTestCase.__qualname__ = self.case
|
||||
ClassTestCase._test_ = self.test
|
||||
serial = 0
|
||||
|
@ -220,7 +274,10 @@ class TestCase:
|
|||
thisCase = self.c.loc[i].to_dict()
|
||||
if not self._matchCaseType(thisCase['Flag']) == 10 and self._matchLevelRun(thisCase['CaseLevel']): continue
|
||||
serial += 1
|
||||
def foo(self, index=i): return self._test_(index)
|
||||
|
||||
def foo(self, index=i):
|
||||
return self._test_(index)
|
||||
|
||||
foo.__doc__ = thisCase['CaseTitle']
|
||||
exec('ClassTestCase.test%s_%s = foo' % (str('%04d' % serial), str(thisCase['CaseId'])))
|
||||
return ClassTestCase
|
||||
|
@ -230,9 +287,11 @@ if __name__ == '__main__':
|
|||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(testCaseClass=TestCase(
|
||||
workbook='D:/Desktop/接口自动化测试用例.xlsx',
|
||||
envs='测试环境',
|
||||
level_list=['P0'],
|
||||
testcase='测试用例'
|
||||
testlves=['P0'],
|
||||
testcase='测试用例',
|
||||
testdata='测试数据',
|
||||
httpconf='请求配置',
|
||||
database='请求配置'
|
||||
).main(), prefix='test'))
|
||||
HTMLTestRunner(verbosity=5, report=os.path.abspath(os.path.join(os.path.dirname(__file__), './1.html'))).run(
|
||||
test_suite)
|
||||
|
|
17
main2.py
17
main2.py
|
@ -1,3 +1,14 @@
|
|||
from Base.Class.Yaml import *
|
||||
print(yaml_decode('sess:\n- json'))
|
||||
|
||||
# from Base.Class.Yaml import *
|
||||
# print(yaml_decode('sess:\n- json'))
|
||||
#
|
||||
# a = {"Host": '127.0.0.1', "User-Agent": 'Chrome'}
|
||||
# b = {"Host": 'www.baidu.com', "User-Agent": 'curl'}
|
||||
# c = {}
|
||||
# c.update(a)
|
||||
# c.update(b)
|
||||
# print(c)
|
||||
#
|
||||
#
|
||||
print(locals().setdefault('a', 123))
|
||||
print(locals().get('a'))
|
||||
print(globals().get('a'))
|
||||
|
|
Loading…
Reference in New Issue