diff --git a/Business/Class/HTMLTestRunner.py b/Business/Class/HTMLTestRunner.py index 89360a3..9965ac2 100644 --- a/Business/Class/HTMLTestRunner.py +++ b/Business/Class/HTMLTestRunner.py @@ -175,7 +175,7 @@ class Template_mixin(object): # 网页模板开始 # 网页模板,变量列表 title, generator, styles, header, report, footer HTML_TMPL = r""" - +
%(script)s+
%(script)s
%(script)s+
%(script)s
开始时间 : 2022-07-30 01:01:38
+开始时间 : 2022-08-01 01:43:42
-合计耗时 : 00:00:00
+合计耗时 : 00:00:01
测试结果 : 总共 3,通过 1,失败 0,错误 2,通过率 33.33%
@@ -493,7 +493,7 @@ function html_escape(s) {pt1_1: -2022-07-30 01:01:38,956 - D: 正在执行:正常登录 -2022-07-30 01:01:39,053 - D: +pt1_1: +2022-08-01 01:43:42,869 - D: 正在执行:正常登录 +2022-08-01 01:43:44,092 - D: [->] POST /filebox.php?op=home HTTP/1.1 Host: www.fanscloud.net @@ -520,12 +520,12 @@ user=&pass=1234ABCDabcd&submitButtonName=%E7%99%BB%E5%BD%95 [<-] HTTP/1.1 200 OK Server: nginx -Date: Fri, 29 Jul 2022 17:01:38 GMT +Date: Sun, 31 Jul 2022 17:43:44 GMT Content-Type: text/html; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding -Set-Cookie: PHPSESSID=8lr8duhbbqtch8t3iu3jq8gsn3; 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 +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 @@ -553,7 +553,7 @@ Content-Encoding: gzipet1_2: -2022-07-30 01:01:39,053 - D: 正在执行:None +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) @@ -566,11 +566,11 @@ KeyError: 0 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 171, in foo + 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 159, in test + 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 116, in test_unit + 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) @@ -596,7 +596,7 @@ KeyError: 0et1_3: -2022-07-30 01:01:39,058 - D: 正在执行:None +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) @@ -609,11 +609,11 @@ KeyError: 0 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 171, in foo + 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 159, in test + 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 116, in test_unit + 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) @@ -638,7 +638,7 @@ KeyError: 01 0 2 -0.101秒 +1.258秒 通过:33.33% diff --git a/Runner/API/DefaultRunner.py b/Runner/API/DefaultRunner.py index 1550e32..04ada8c 100644 --- a/Runner/API/DefaultRunner.py +++ b/Runner/API/DefaultRunner.py @@ -8,42 +8,90 @@ from Base.Class.Logger import * log = Logger(name='test', level='DEBUG') class TestCase: - def __init__(self, workbook, data='数据配置', case='测试用例', envs='测试环境', level_list=None): + _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 + ): + if workbook_config is None: workbook_config = {} + tabs = self._merge_dict( + { + 'HTTPConf': { + 'sheet': httpconf + }, + 'DataBase': { + 'sheet': database + }, + 'TestData': { + 'sheet': testdata + }, + 'TestCase': { + 'sheet': testcase + } + } + , workbook_config) + # tabs = { + # 'HTTPConf': { + # 'sheet': '数据配置' + # }, + # 'DataBase': { + # 'sheet': '数据配置' + # }, + # 'TestData': { + # 'sheet': '数据配置' + # }, + # 'TestCase': { + # 'sheet': '测试用例' + # } + # } + import os from pandas.core.frame import DataFrame - self._g = {} - self._l = {} - self.case = case - self.envs = envs - self.http = Request init = Excel().open(workbook, read_only=True) - init_data = auto_decode(init.select(data).cellGet(0, 0)) - init_case = auto_decode(init.select(case).cellGet(0, 0)) - self.cell_list = { - 'item': - auto_decode(init.select(case).cellGet(cell=init_case['fixeds']['item'])), - 'mode': - auto_decode(init.select(case).cellGet(cell=init_case['fixeds']['mode'])) - } - self.view_list = { - 'http': - DataFrame(read_view_dict(filename=workbook, sheet=data, area=init_data['tables']['http']['views'], fields=init_data['tables']['http']['field'], auto_truncate=True)), - 'base': - DataFrame(read_view_dict(filename=workbook, sheet=data, area=init_data['tables']['base']['views'], fields=init_data['tables']['base']['field'], auto_truncate=True)), - 'data': - DataFrame(read_view_dict(filename=workbook, sheet=data, area=init_data['tables']['data']['views'], fields=init_data['tables']['data']['field'], auto_truncate=True)), - 'case': - DataFrame(read_view_dict(filename=workbook, sheet=case, area=init_case['tables']['case']['views'], fields=init_case['tables']['case']['field'], auto_truncate=True)) - } - self.i = self.cell_list['item'] - self.m = self.cell_list['mode'] - self.h = self.view_list['http'] - self.b = self.view_list['base'] - self.d = self.view_list['data'] - self.c = self.view_list['case'] - init.exit() + 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) + data[k] = {} + if 'fixed' in v.keys(): + data[k]['fixed'] = {} + for key, value in v['fixed'].items(): + 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)) + 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) + + self.i = data['TestCase']['fixed']['ItemName'] + self.m = data['TestCase']['fixed']['SessMode'] + self.h = data['HTTPConf']['views'] + self.b = data['DataBase']['views'] + self.d = data['TestData']['views'] + self.c = data['TestCase']['views'] + self._setLevels(level_list) self._setRequestMode(self.m) - self.dirs = os.path.dirname(workbook) + def _setRequestMode(self, value=None): self.http = [Request, Session][value in ['会话模式', 'Session', 'session']]() @@ -78,6 +126,19 @@ class TestCase: return True return value in self.leve_list + def _merge_dict(self, dict_ori, dict_add): + if isinstance(dict_ori, dict) and isinstance(dict_add, dict): + for k, v in dict_ori.items(): + if k in dict_add.keys(): + if isinstance(v, dict): + dict_ori[k] = self._merge_dict(dict_ori[k], dict_add[k]) + else: + dict_ori[k] = dict_add[k] + for k, v in dict_add.items(): + if k not in dict_ori.keys(): + dict_ori[k] = dict_add[k] + return dict_ori + @staticmethod def _sub_variable(text='', vars_dict=None): if not isinstance(text, str): @@ -112,43 +173,34 @@ class TestCase: return data def test_unit(self, data): + # 开始测试 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() - res_kwargs = { - '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'] + 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'] } - HTTPParamType = self._matchParmType(data['HTTPParamType']) - match HTTPParamType: + match self._matchParmType(data['HTTPParamType']): case 10: - res_kwargs['data_json'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent'])) + resKwArgs['data_json'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent'])) case 20: - res_kwargs['data'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent'])) + resKwArgs['data'] = self._sub_variable_auto(auto_decode(data['HTTPParamContent'])) case _: - res_kwargs['data'] = self._sub_variable_auto(data['HTTPParamContent']) + resKwArgs['data'] = self._sub_variable_auto(data['HTTPParamContent']) HTTPParamOfFile = self._sub_variable_auto(auto_decode(data['HTTPParamOfFile'])) if isinstance(HTTPParamOfFile, dict): - for k, v in HTTPParamOfFile: - HTTPParamOfFile[k] = open(os.path.abspath(os.path.join(self.dirs, './%s' % v)), 'rb') - res_kwargs['data_file'] = HTTPParamOfFile + 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 - res = self.http.http(**res_kwargs) + res = self.http.http(**resKwArgs) log.d('\n%s' % (res['brief'] or '')) # print(res) # print(HTTPCh) @@ -178,10 +230,9 @@ if __name__ == '__main__': test_suite = unittest.TestSuite() test_suite.addTest(unittest.makeSuite(testCaseClass=TestCase( workbook='D:/Desktop/接口自动化测试用例.xlsx', - data='数据配置', - case='测试用例', envs='测试环境', - level_list=['P0'] + level_list=['P0'], + testcase='测试用例' ).main(), prefix='test')) HTMLTestRunner(verbosity=5, report=os.path.abspath(os.path.join(os.path.dirname(__file__), './1.html'))).run( test_suite) diff --git a/main2.py b/main2.py index c5c73f0..4aa5642 100644 --- a/main2.py +++ b/main2.py @@ -1,2 +1,3 @@ -import os -print(os.path.abspath(os.path.join(os.path.dirname(__file__), './'))) \ No newline at end of file +from Base.Class.Yaml import * +print(yaml_decode('sess:\n- json')) +