diff --git a/case_utils/request_data_handle.py b/case_utils/request_data_handle.py index ceb21d1..4d0ae46 100644 --- a/case_utils/request_data_handle.py +++ b/case_utils/request_data_handle.py @@ -5,7 +5,9 @@ # @File : request_data_handle.py # @Software: PyCharm # @Desc: 处理request请求前后的用例数据 +import json +import requests from common_utils.data_handle import eval_data_process, data_replace from config.global_vars import GLOBAL_VARS @@ -26,17 +28,17 @@ class RequestPreDataHandle: def __init__(self, request_data): logger.debug(f"\n======================================================\n" \ "-------------Start:处理用例数据前--------------------\n" - f"用例标题: {request_data.get('title', None)}\n" \ - f"请求路径: {request_data.get('url', None)}\n" \ - f"请求方式: {request_data.get('method', None)}\n" \ - f"请求头: {request_data.get('headers', None)}\n" \ - f"请求cookies: {request_data.get('cookies', None)}\n" \ - f"请求关键字: {request_data.get('pk', None)}\n" \ - f"请求内容: {request_data.get('payload', None)}\n" \ - f"请求文件: {request_data.get('files', None)}\n" \ - f"后置提取参数: {request_data.get('extract', None)}\n" \ - f"响应断言: {request_data.get('assert_response', None)}\n" \ - f"数据库断言: {request_data.get('assert_sql', None)}\n" \ + f"用例标题: {type(request_data.get('title', None))} || {request_data.get('title', None)}\n" \ + f"请求路径: {type(request_data.get('url', None))} || {request_data.get('url', None)}\n" \ + f"请求方式: {type(request_data.get('method', None))} || {request_data.get('method', None)}\n" \ + f"请求头: {type(request_data.get('headers', None))} || {request_data.get('headers', None)}\n" \ + f"请求cookies: {type(request_data.get('cookies', None))} || {request_data.get('cookies', None)}\n" \ + f"请求类型: {type(request_data.get('pk', None))} || {request_data.get('pk', None)}\n" \ + f"请求内容: {type(request_data.get('payload', None))} || {request_data.get('payload', None)}\n" \ + f"请求文件: {type(request_data.get('files', None))} || {request_data.get('files', None)}\n" \ + f"后置提取参数: {type(request_data.get('extract', None))} || {request_data.get('extract', None)}\n" \ + f"响应断言: {type(request_data.get('assert_response', None))} || {request_data.get('assert_response', None)}\n" \ + f"数据库断言: {type(request_data.get('assert_sql', None))} || {request_data.get('assert_sql', None)}\n" \ "=====================================================") self.request_data = request_data @@ -54,69 +56,90 @@ class RequestPreDataHandle: self.assert_handle() logger.debug(f"\n======================================================\n" \ "-------------End:处理用例数据后--------------------\n" - f"用例标题: {self.request_data.get('title', None)}\n" \ - f"请求路径: {self.request_data.get('url', None)}\n" \ - f"请求方式: {self.request_data.get('method', None)}\n" \ - f"请求头: {self.request_data.get('headers', None)}\n" \ - f"请求cookies: {self.request_data.get('cookies', None)}\n" \ - f"请求关键字: {self.request_data.get('pk', None)}\n" \ - f"请求内容: {self.request_data.get('payload', None)}\n" \ - f"请求文件: {self.request_data.get('files', None)}\n" \ - f"后置提取参数: {self.request_data.get('extract', None)}\n" \ - f"响应断言: {self.request_data.get('assert_response', None)}\n" \ - f"数据库断言: {self.request_data.get('assert_sql', None)}\n" \ + f"用例标题: {type(self.request_data.get('title', None))} || {self.request_data.get('title', None)}\n" \ + f"请求路径: {type(self.request_data.get('url', None))} || {self.request_data.get('url', None)}\n" \ + f"请求方式: {type(self.request_data.get('method', None))} || {self.request_data.get('method', None)}\n" \ + f"请求头: {type(self.request_data.get('headers', None))} || {self.request_data.get('headers', None)}\n" \ + f"请求cookies: {type(self.request_data.get('cookies', None))} || {self.request_data.get('cookies', None)}\n" \ + f"请求类型: {type(self.request_data.get('pk', None))} || {self.request_data.get('pk', None)}\n" \ + f"请求内容: {type(self.request_data.get('payload', None))} || {self.request_data.get('payload', None)}\n" \ + f"请求文件: {type(self.request_data.get('files', None))} || {self.request_data.get('files', None)}\n" \ + f"后置提取参数: {type(self.request_data.get('extract', None))} || {self.request_data.get('extract', None)}\n" \ + f"响应断言: {type(self.request_data.get('assert_response', None))} || {self.request_data.get('assert_response', None)}\n" \ + f"数据库断言: {type(self.request_data.get('assert_sql', None))} || {self.request_data.get('assert_sql', None)}\n" \ "=====================================================") return self.request_data def url_handle(self): - """ - 用例数据中获取到的url(一般是不带host的,个别特殊的带有host,则不进行处理) - """ - # 检测url中是否存在需要替换的参数,如果存在则进行替换 - data_replace(content=self.request_data.get("url", None), source=GLOBAL_VARS) - # 进行url处理,最终得到full_url - host = GLOBAL_VARS.get("host", "") - url = self.request_data.get("url", "") - # 从用例数据中获取url,如果键url不存在,则返回空字符串 - # 如果url是以http开头的,则直接使用该url,不与host进行拼接 - if url.lower().startswith("http"): - full_url = url - else: - # 如果host以/结尾 并且 url以/开头 - if host.endswith("/") and url.startswith("/"): - full_url = host[0:len(host) - 1] + url - # 如果host以/结尾 并且 url不以/开头 - elif host.endswith("/") and (not url.startswith("/")): - full_url = host + url - elif (not host.endswith("/")) and url.startswith("/"): - # 如果host不以/结尾 且 url以/开头,则将host和url拼接起来,组成新的url - full_url = host + url + try: + """ + 用例数据中获取到的url(一般是不带host的,个别特殊的带有host,则不进行处理) + """ + # 检测url中是否存在需要替换的参数,如果存在则进行替换 + data_replace(content=self.request_data.get("url", None), source=GLOBAL_VARS) + # 进行url处理,最终得到full_url + host = GLOBAL_VARS.get("host", "") + url = self.request_data.get("url", "") + # 从用例数据中获取url,如果键url不存在,则返回空字符串 + # 如果url是以http开头的,则直接使用该url,不与host进行拼接 + if url.lower().startswith("http"): + full_url = url else: - # 如果host不以/结尾 且 url不以/开头,则将host和url拼接起来的时候增加/,组成新的url - full_url = host + "/" + url - self.request_data["url"] = full_url + # 如果host以/结尾 并且 url以/开头 + if host.endswith("/") and url.startswith("/"): + full_url = host[0:len(host) - 1] + url + # 如果host以/结尾 并且 url不以/开头 + elif host.endswith("/") and (not url.startswith("/")): + full_url = host + url + elif (not host.endswith("/")) and url.startswith("/"): + # 如果host不以/结尾 且 url以/开头,则将host和url拼接起来,组成新的url + full_url = host + url + else: + # 如果host不以/结尾 且 url不以/开头,则将host和url拼接起来的时候增加/,组成新的url + full_url = host + "/" + url + self.request_data["url"] = full_url + except Exception as e: + logger.error(f"处理url报错了:{e}") + print(f"处理url报错了:{e}") def method_handle(self): # TODO 暂时不需要处理,后续有需要在处理 pass def cookies_handle(self): - # 从用例数据中获取cookies, 处理cookies - if self.request_data.get("cookies", None): - self.request_data["cookies"] = eval_data_process( - data_replace(content=self.request_data.get("cookies", None), source=GLOBAL_VARS)) + try: + # 从用例数据中获取cookies, 处理cookies + if self.request_data.get("cookies", None): + # 检测替换后的cookies是否为字典类型,如果不是,则使用json.loads转换 + cookies = data_replace(content=self.request_data.get("cookies"), source=GLOBAL_VARS) + if isinstance(cookies, str): + # 使用json的loads函数,把str转化为字典,再将字典恢复成原来的cookies + self.request_data["cookies"] = requests.utils.cookiejar_from_dict(json.loads(cookies)) + else: + self.request_data["cookies"] = cookies + except Exception as e: + logger.error(f"处理cookies报错了:{e}") + print(f"处理cookies报错了:{e}") def headers_handle(self): - # 从用例数据中获取header, 处理header - if self.request_data.get("headers", None): - self.request_data["headers"] = eval_data_process( - data_replace(content=self.request_data.get("headers", None), source=GLOBAL_VARS)) + try: + # 从用例数据中获取header, 处理header + if self.request_data.get("headers", None): + self.request_data["headers"] = eval_data_process( + data_replace(content=self.request_data.get("headers"), source=GLOBAL_VARS)) + except Exception as e: + logger.error(f"处理header报错了:{e}") + print(f"处理header报错了:{e}") def payload_handle(self): - # 处理请求参数payload - if self.request_data.get("payload", None): - self.request_data["payload"] = eval_data_process( - data_replace(content=self.request_data.get("payload", None), source=GLOBAL_VARS)) + try: + # 处理请求参数payload + if self.request_data.get("payload", None): + self.request_data["payload"] = eval_data_process( + data_replace(content=self.request_data.get("payload"), source=GLOBAL_VARS)) + except Exception as e: + logger.error(f"处理payload报错了:{e}") + print(f"处理payload报错了:{e}") def files_handle(self): # 处理文件 @@ -124,17 +147,25 @@ class RequestPreDataHandle: pass def extract_handle(self): - # 处理后置提取参数 - if self.request_data.get("extract", None): - # 仅提取参数中的python表达式,不需要进行数据替换 - self.request_data["extract"] = eval_data_process(self.request_data.get("extract", None)) + try: + # 处理后置提取参数 + if self.request_data.get("extract", None): + # 仅提取参数中的python表达式,不需要进行数据替换 + self.request_data["extract"] = eval_data_process(self.request_data.get("extract")) + except Exception as e: + logger.error(f"处理extract报错了:{e}") + print(f"处理extract报错了:{e}") def assert_handle(self): - # 处理响应断言参数 - if self.request_data.get("assert_response", None): - self.request_data["assert_response"] = eval_data_process( - data_replace(content=self.request_data.get("assert_response", None), source=GLOBAL_VARS)) - # 由于数据库断言里面的变量需要请求响应后进行提取,因此目前不进行处理 + try: + # 处理响应断言参数 + if self.request_data.get("assert_response", None): + self.request_data["assert_response"] = eval_data_process( + data_replace(content=self.request_data.get("assert_response"), source=GLOBAL_VARS)) + # 由于数据库断言里面的变量需要请求响应后进行提取,因此目前不进行处理 + except Exception as e: + logger.error(f"处理assert报错了:{e}") + print(f"处理assert报错了:{e}") # ---------------------------------------- 进行请求,请求后的参数提取处理----------------------------------------# @@ -157,14 +188,14 @@ class RequestHandle: data_replace(content=self.case_data["assert_sql"], source=GLOBAL_VARS)) logger.info(f"\n======================================================\n" \ "-------------请求数据--------------------\n" - f"用例标题: {self.case_data.get('title', None)}\n" \ - f"请求路径: {self.case_data.get('url', None)}\n" \ - f"请求方式: {self.case_data.get('method', None)}\n" \ - f"请求头: {self.case_data.get('headers', None)}\n" \ - f"请求cookies: {self.case_data.get('cookies', None)}\n" \ - f"请求关键字: {self.case_data.get('pk', None)}\n" \ - f"请求内容: {self.case_data.get('payload', None)}\n" \ - f"请求文件: {self.case_data.get('files', None)}\n" \ + f"用例标题: {type(self.case_data.get('title', None))} || {self.case_data.get('title', None)}\n" \ + f"请求路径: {type(self.case_data.get('url', None))} || {self.case_data.get('url', None)}\n" \ + f"请求方式: {type(self.case_data.get('method', None))} || {self.case_data.get('method', None)}\n" \ + f"请求头: {type(self.case_data.get('headers', None))} || {self.case_data.get('headers', None)}\n" \ + f"请求cookies: {type(self.case_data.get('cookies', None))} || {self.case_data.get('cookies', None)}\n" \ + f"请求类型: {type(self.case_data.get('pk', None))} || {self.case_data.get('pk', None)}\n" \ + f"请求内容: {type(self.case_data.get('payload', None))} || {self.case_data.get('payload', None)}\n" \ + f"请求文件: {type(self.case_data.get('files', None))} || {self.case_data.get('files', None)}\n" \ f"请求响应数据: {response.text}\n" \ f"请求响应码: {response.status_code}\n" \ f"响应耗时: {round(response.elapsed.total_seconds(), 2)} s || {round(response.elapsed.total_seconds() * 1000, 2)} ms\n" \ @@ -172,12 +203,13 @@ class RequestHandle: allure_step(step_title=f"请求地址:{self.case_data['url']}") allure_step(step_title=f"请求方式:{self.case_data['method']}") allure_step(step_title="请求头", content=self.case_data['headers']) - allure_step(step_title="请求Cookies", content=self.case_data['cookies']) + allure_step(step_title="请求Cookies", content=str(self.case_data['cookies'])) allure_step(step_title="请求参数", content=self.case_data['payload']) allure_step(step_title="请求文件", content=self.case_data['files']) allure_step(step_title="请求响应数据", content=response.text) allure_step(step_title=f"请求响应码:{response.status_code}") - allure_step(step_title=f"响应耗时:{round(response.elapsed.total_seconds(), 2)} s || {round(response.elapsed.total_seconds() * 1000, 2)} ms") + allure_step( + step_title=f"响应耗时:{round(response.elapsed.total_seconds(), 2)} s || {round(response.elapsed.total_seconds() * 1000, 2)} ms") return response @@ -195,16 +227,19 @@ def after_request_extract(response: Response, extract): "=====================================================") result = {} if extract: - if response_type(response) == "json": - # 如果响应数据是json格式,则将按照json方式对后置提取参数进行处理 - res = response.json() - for k, v in extract.items(): - result[k] = json_extractor(res, v) - else: - # 如果响应数据是str格式,则将按照str方式对后置提取参数进行处理 - res = response.text - for k, v in extract.items(): - result[k] = re_extract(res, v) + try: + if response_type(response) == "json": + # 如果响应数据是json格式,则将按照json方式对后置提取参数进行处理 + res = response.json() + for k, v in extract.items(): + result[k] = json_extractor(res, v) + else: + # 如果响应数据是str格式,则将按照str方式对后置提取参数进行处理 + res = response.text + for k, v in extract.items(): + result[k] = re_extract(res, v) + except Exception as e: + logger.error(f"提取后置参数报错:{e}") logger.debug(f"\n======================================================\n" \ "-------------End:从响应数据中提取后置参数保存到全局变量--------------------\n" f"后置提取参数(新): {result}\n" \ diff --git a/data/1test_login_demo.yaml b/data/test_login_demo.yaml similarity index 100% rename from data/1test_login_demo.yaml rename to data/test_login_demo.yaml diff --git a/test_case/test_manual_case/1test_demo.py b/test_case/test_manual_case/test_demo.py similarity index 100% rename from test_case/test_manual_case/1test_demo.py rename to test_case/test_manual_case/test_demo.py