From de4a32562a0b36694b0e56e144bc4f00c01f06b6 Mon Sep 17 00:00:00 2001 From: floraachy <1622042529@qq.com> Date: Tue, 23 Jul 2024 17:38:58 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8C=87=E5=AE=9A=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E6=8F=90=E5=8F=96=E6=9D=A5=E6=BA=90=EF=BC=8C=E4=BB=8E?= =?UTF-8?q?=E5=93=8D=E5=BA=94=E6=95=B0=E6=8D=AE=EF=BC=8C=E7=94=A8=E4=BE=8B?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=EF=BC=8C=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=AD?= =?UTF-8?q?=E9=80=9A=E8=BF=87jsonpath=E5=92=8C=E6=AD=A3=E5=88=99=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=96=B9=E5=BC=8F=E6=8F=90=E5=8F=96=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 99 ++++-- config/settings.py | 337 +++++++++----------- utils/case_generate_utils/case_template.txt | 5 +- utils/requests_utils/request_control.py | 128 +++++--- 4 files changed, 311 insertions(+), 258 deletions(-) diff --git a/README.md b/README.md index 2e9a0d1..18282c6 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ * 支持利用allure设置用例优先级,运行指定优先级的用例 * 执行环境一键切换,解决多环境相互影响问题 * 自动生成用例代码: 测试人员在yaml/excel文件中填写好测试用例, 程序可以直接生成用例代码,纯小白也能使用 -* 支持参数多类型提取:支持通过jsonpath从response.json提取数据;支持通过正则表达式从response.text提取数据;支持直接提取response本身的数据,例如response.cookies +* 支持参数多类型提取:支持从响应数据,数据库,用例数据中通过jsonpath或者正则方式提取数据 * 使用Allure生成测试报告,并对测试报告进行了定制化修改,使得测试报告更加美观 * 日志模块: 采用loguru管理日志,可以输出更为优雅,简洁的日志 * 钉钉、企业微信通知: 支持多种通知场景,执行成功之后,可选择发送钉钉、或者企业微信、邮箱通知 @@ -191,45 +191,78 @@ case_info: # 具体的用例数据,是以列表的形式进行管理 ``` ### 6. 参数提取说明 +目前支持从响应数据(response)、数据库(database)、用例数据(case)中提取数据。 目前支持3种方式的参数提取:type_jsonpath, type_re, type_response -#### type_jsonpath -如果采用jsonpath方式从响应数据提取参数,`extract`的key是`type_jsonpath`; `extract[type_jsonpath]`的key是变量名,value是提取表达式; -参考示例: +注意: +- 提取来源关键字:case, response, database必须保持完全一致; +- 提取方式关键字:type_jsonpath, type_re, type_response必须保持完全一致; + +#### 从响应数据中提取参数 +目前从响应数据中提取参数,支持提取方式:type_jsonpath, type_re, type_response。 + +参考写法如下: +``` + extract: + response: + type_jsonpath: + res_j_nickname: $.username + type_re: + res_re_nickname: \"username":"(.*?)" + type_response: + cookies1: response.cookies +``` + +其中`res_j_nickname`表示提取的变量名,后续会保存在全局变量`GLOBAL_VARS`中, 可以直接在其他接口中使用:`${res_j_nickname}` +其中`$.username`表示提取表达式,根据提取方式来写不同的表达式,表达式要写正确,否则提取不到值。 +注意: +- jsonpath提取方式`type_jsonpath`,如果提取到的值是长度为1的列表,会自动获取第一个元素,其值类型由list变更为str。例如通过`name: $.data` 提取到的值是:`["flora"]`, 最后name的值会是`"flora"`。 +- 正则表达式提取方式`type_re`,如果提取到的值是长度为1的列表,会自动获取第一个元素,其值类型由list变更为str。例如通过`name: "username":"(.*?)"` 提取到的值是:`["flora"]`, 最后name的值会是`"flora"`。 +- 响应对应提取方式`type_response`, 则可以获取Reponse对应自带方法的一些值,例如`response.status_code`, `response.cookies`, `response.text`, `response.headers`, `response.is_redirect`等。; + + + +注意:之前老版本是没有指定提取来源的,本次更新兼容了老版本的写法: ``` extract: type_jsonpath: - nickname: $.username - login: $.login - user_id: $.user_id -``` -注意:如果提取到的值是长度为1的列表,会自动获取第一个元素,其值类型由list变更为str。例如通过`name: $.data` 提取到的值是:`["flora"]`, 最后name的值会是`"flora"`。 - - -#### type_re -如果采用正则表达式方式从响应数据提取参数,`extract`的key是`type_re`; `extract[type_re]`的key是变量名,value是提取表达式; - -参考示例: -``` - # 注意:\是用来转译的,保证yaml格式正确.也可以用引号包裹起来 - extract: + res_j_nickname: $.username type_re: - nickname: \"username":"(.*?)" - login: \"login":"(.*?)" - user_id: '"user_id":(.*?),' -``` -注意:如果提取到的值是长度为1的列表,会自动获取第一个元素,其值类型由list变更为str。例如通过`name: "username":"(.*?)"` 提取到的值是:`["flora"]`, 最后name的值会是`"flora"`。 - -#### type_response -如果是直接从响应数据提取参数,`extract`的key是`type_response`; `extract[type_response]`的key是变量名,value是提取表达式; - -基本上response所有方法都支持,部分参考:`response.status_code`, `response.cookies`, `response.text`, `response.headers`, `response.is_redirect` - -参考示例: -``` - extract: + res_re_nickname: \"username":"(.*?)" type_response: - cookies: response.cookies + cookies1: response.cookies +``` + + +#### 从用例数据中提取参数 +目前从响应数据中提取参数,支持提取方式:type_jsonpath, type_re。 + +参考写法如下: +``` + case: + type_jsonpath: + case_login: $.payload.login + type_re: + case_url_key: "'url': 'https?://[^/]+/api/(.*?)/login.json'" +``` +注意:假如需要提取url中的参数,由于url我们是处理过的。比如用例数据中的url是`/api/login.json`,但是实际执行过程中的url是带有域名的 `https://www.gitlink.org.cn/api/login.json` ,因此提取表达式需要将目标值对准是有域名的url。 + +#### 从数据库中提取参数 +目前从响应数据中提取参数,支持提取方式:type_jsonpath, type_re。 + +注意: +- 查询数据库的方法我用的是查询所有,如果有多条符合条件的数据,则返回所有数据。查询结果是list格式; +- 如果不需要查询数据库,`setting.py`中的`ENV_VARS`中对应环境的`db_info`字段为空。代码中判断了`db_info`字段不为空,才进行数据库参数提取。 + +参考写法如下: +``` + database: + # 数据库查询用的是查询所有符合条件的数据,查询结果是一个列表 + sql: select * from users limit 2; + type_re: + sql_re_nickname: "'login': '(.*?)'" + type_jsonpath: + sql_j_login: $..login ``` ### 7. 断言方式 diff --git a/config/settings.py b/config/settings.py index a3fdea4..0931dfb 100644 --- a/config/settings.py +++ b/config/settings.py @@ -17,209 +17,170 @@ ENV_VARS = { }, "test": { # 环境相关域名 - "host": "https://******", - "wiki_host": "https://******", - "pms_host": "https://******", - "glcc_host": "https://******", - # 获取oauth_token需要的参数 - "client_id": "****client_id****", - "client_secret": "****client_secret****", - # 万能验证码 - "green_code": "******", - # 测试账号 - 普通用户(测试仓库开发者), 默认登录账号 - "env_login": "******", - "env_password": "******", # 运行时需要手动更改密码 - "env_nickname": "******", - "env_user_id": 106, - # 测试账号 - 普通用户(测试仓库报告者) - "t_login": "******", - "t_password": "******", - "t_nickname": "******", - "t_user_id": 290, - # 测试账号 - 超级管理员(测试仓库管理员) - "env_super_login": "******", - "env_super_password": "******", # 运行时需要手动更改密码 - # 测试仓库 env_repo_owner/env_repo_identifier - "env_repo_owner": "******", - "env_repo_identifier": "******", - "env_project_id": "", - # pms相关环境变量 - 产品 - "env_pms_product_id": "", - "env_pms_product_identifier": "", - # pms相关环境变量 - 项目 - "env_pms_project_id": "", - # pms相关环境变量 - 企业 - "env_enterprise_identifier": "", - "env_enterprise_id": "", - "env_organization_id": 249, - "env_dept_id": 349, - # 数据库配置 - "db_info": { - "db_host": "xx.xx.xx.xx", - "db_port": 3306, - "db_user": "root", - "db_pwd": "**********", - "db_database": "test**********", - "ssh": False, - "ssh_host": "xx.xx.xx.xx", - "ssh_port": 3306, - "ssh_user": "root", - "ssh_pwd": "**********" - - } - - }, - "dev": { - # 环境相关域名 - "host": "http://******", + "host": "", "wiki_host": "", - "pms_host": "http://******", + "pms_host": "", + "glcc_host": "", # 获取oauth_token需要的参数 - "client_id": "****client_id****", - "client_secret": "****client_secret****", + "client_id": "", + "client_secret": "*", # 万能验证码 - "green_code": "******", + "green_code": "", # 测试账号 - 普通用户(测试仓库开发者), 默认登录账号 - "env_login": "******", - "env_password": "******", # 运行时需要手动更改密码 - "env_nickname": "******", - "env_user_id": 36669, + "env_login": "", + "env_password": "", # 运行时需要手动更改密码 + "env_nickname": "", + "env_user_id": 0, + # 测试账号 - 普通用户(测试仓库报告者) + "t_login": "", + "t_password": "", + "t_nickname": "", + "t_user_id": 0, # 测试账号 - 超级管理员(测试仓库管理员) - "env_super_login": "******", - "env_super_password": "******", - "env_super_nickname": "******", - "env_super_user_id": 36661, - # 测试账号 - 普通用户(测试仓库报告者) - "t_login": "******", - "t_password": "******", - "t_nickname": "******", - "t_user_id": 36670, - # 测试仓库 env_repo_owner/env_repo_identifier - "env_repo_owner": "******", - "env_repo_identifier": "******", - "env_project_id": "****", - # pms相关环境变量 - 产品 - "env_pms_product_id": "", - "env_pms_product_identifier": "", - # pms相关环境变量 - 项目 - "env_pms_project_id": "", - # pms相关环境变量 - 企业 - "env_enterprise_identifier": "", - "env_enterprise_id": "", - "env_organization_id": 36663, - "env_dept_id": 331, - # 数据库配置 - "db_info": { - "db_host": "xx.xx.xx.xx", - "db_port": 3306, - "db_user": "root", - "db_pwd": "**********", - "db_database": "test**********", - "ssh": False, - "ssh_host": "xx.xx.xx.xx", - "ssh_port": 3306, - "ssh_user": "root", - "ssh_pwd": "**********" - - } - - }, - "pre": { - # 环境相关域名 - "host": "http://******", - "wiki_host": "http://******", - "pms_host": "https://******", - # 获取oauth_token需要的参数 - "client_id": "****client_id-pre****", - "client_secret": "****client_secret-pre****", - # 万能验证码 - "green_code": "******", - # 测试账号 - 普通用户(测试仓库开发者), 默认登录账号 - "env_login": "******", - "env_password": "******", # 运行时需要手动更改密码 - "env_nickname": "******", - "env_user_id": 115, - # 测试账号 - 普通用户(测试仓库报告者) - "t_login": "******", - "t_password": "******", - "t_nickname": "******", - "t_user_id": 36546, - # 测试账号 - 超级管理员(测试仓库管理员) - "env_super_login": "******", - "env_super_password": "******", # 运行时需要手动更改密码 - "env_super_user_id": 110, - # 测试仓库 env_repo_owner/env_repo_identifier - "env_repo_owner": "******", - "env_repo_identifier": "******", - "env_project_id": "******", - # pms相关环境变量 - "env_pms_product_id": "", - "env_pms_product_identifier": "", - "env_pms_project_id": "", - "env_dept_id": "", - # 数据库配置 - "db_info": { - "db_host": "xx.xx.xx.xx", - "db_port": 3306, - "db_user": "root", - "db_pwd": "**********", - "db_database": "test**********", - "ssh": False, - "ssh_host": "xx.xx.xx.xx", - "ssh_port": 3306, - "ssh_user": "root", - "ssh_pwd": "**********" - - } - - }, - "live": { - # 环境相关域名 - "host": "https://******", - "wiki_host": "https://******", - "pms_host": "https://*****", - # 获取oauth_token需要的参数 - "client_id": "****client_id-live****", - "client_secret": "****client_secret-live****", - # 万能验证码 - "green_code": "****green_code-live****", - # 测试账号 - (测试仓库开发者), 默认登录账号 - "env_login": "******", - "env_password": "******", - "env_nickname": "******", - "env_user_id": 87611, - # 测试账号 - 普通用户(测试仓库报告者) - "t_login": "******", - "t_password": "******", - "t_nickname": "******", - "t_user_id": 87691, - # 测试账号 - 超级管理员 (测试仓库管理员) "env_super_login": "", - "env_super_password": "", - "env_super_user_id": 0, + "env_super_password": "", # 运行时需要手动更改密码 # 测试仓库 env_repo_owner/env_repo_identifier "env_repo_owner": "", "env_repo_identifier": "", "env_project_id": "", - # pms相关环境变量 + # pms相关环境变量 - 产品 "env_pms_product_id": "", "env_pms_product_identifier": "", + # pms相关环境变量 - 项目 "env_pms_project_id": "", - "env_dept_id": "", + # pms相关环境变量 - 企业 + "env_enterprise_identifier": "", + "env_enterprise_id": "", + "env_organization_id": 0, + "env_dept_id": 0, # 数据库配置 - "db_info": { - "db_host": "xx.xx.xx.xx", - "db_port": 3306, - "db_user": "root", - "db_pwd": "**********", - "db_database": "test**********", - "ssh": True, - "ssh_host": "xx.xx.xx.xx", - "ssh_port": 3306, - "ssh_user": "root", - "ssh_pwd": "**********" + "db_info": {} - } + }, + "dev": { + # 环境相关域名 + "host": "", + "wiki_host": "", + "pms_host": "", + "glcc_host": "", + # 获取oauth_token需要的参数 + "client_id": "", + "client_secret": "*", + # 万能验证码 + "green_code": "", + # 测试账号 - 普通用户(测试仓库开发者), 默认登录账号 + "env_login": "", + "env_password": "", # 运行时需要手动更改密码 + "env_nickname": "", + "env_user_id": 0, + # 测试账号 - 普通用户(测试仓库报告者) + "t_login": "", + "t_password": "", + "t_nickname": "", + "t_user_id": 0, + # 测试账号 - 超级管理员(测试仓库管理员) + "env_super_login": "", + "env_super_password": "", # 运行时需要手动更改密码 + # 测试仓库 env_repo_owner/env_repo_identifier + "env_repo_owner": "", + "env_repo_identifier": "", + "env_project_id": "", + # pms相关环境变量 - 产品 + "env_pms_product_id": "", + "env_pms_product_identifier": "", + # pms相关环境变量 - 项目 + "env_pms_project_id": "", + # pms相关环境变量 - 企业 + "env_enterprise_identifier": "", + "env_enterprise_id": "", + "env_organization_id": 0, + "env_dept_id": 0, + # 数据库配置 + "db_info": {} + + }, + "pre": { + # 环境相关域名 + "host": "", + "wiki_host": "", + "pms_host": "", + "glcc_host": "", + # 获取oauth_token需要的参数 + "client_id": "", + "client_secret": "*", + # 万能验证码 + "green_code": "", + # 测试账号 - 普通用户(测试仓库开发者), 默认登录账号 + "env_login": "", + "env_password": "", # 运行时需要手动更改密码 + "env_nickname": "", + "env_user_id": 0, + # 测试账号 - 普通用户(测试仓库报告者) + "t_login": "", + "t_password": "", + "t_nickname": "", + "t_user_id": 0, + # 测试账号 - 超级管理员(测试仓库管理员) + "env_super_login": "", + "env_super_password": "", # 运行时需要手动更改密码 + # 测试仓库 env_repo_owner/env_repo_identifier + "env_repo_owner": "", + "env_repo_identifier": "", + "env_project_id": "", + # pms相关环境变量 - 产品 + "env_pms_product_id": "", + "env_pms_product_identifier": "", + # pms相关环境变量 - 项目 + "env_pms_project_id": "", + # pms相关环境变量 - 企业 + "env_enterprise_identifier": "", + "env_enterprise_id": "", + "env_organization_id": 0, + "env_dept_id": 0, + # 数据库配置 + "db_info": {} + + }, + "live": { + # 环境相关域名 + "host": "", + "wiki_host": "", + "pms_host": "", + "glcc_host": "", + # 获取oauth_token需要的参数 + "client_id": "", + "client_secret": "*", + # 万能验证码 + "green_code": "", + # 测试账号 - 普通用户(测试仓库开发者), 默认登录账号 + "env_login": "", + "env_password": "", # 运行时需要手动更改密码 + "env_nickname": "", + "env_user_id": 0, + # 测试账号 - 普通用户(测试仓库报告者) + "t_login": "", + "t_password": "", + "t_nickname": "", + "t_user_id": 0, + # 测试账号 - 超级管理员(测试仓库管理员) + "env_super_login": "", + "env_super_password": "", # 运行时需要手动更改密码 + # 测试仓库 env_repo_owner/env_repo_identifier + "env_repo_owner": "", + "env_repo_identifier": "", + "env_project_id": "", + # pms相关环境变量 - 产品 + "env_pms_product_id": "", + "env_pms_product_identifier": "", + # pms相关环境变量 - 项目 + "env_pms_project_id": "", + # pms相关环境变量 - 企业 + "env_enterprise_identifier": "", + "env_enterprise_id": "", + "env_organization_id": 0, + "env_dept_id": 0, + # 数据库配置 + "db_info": {} } } diff --git a/utils/case_generate_utils/case_template.txt b/utils/case_generate_utils/case_template.txt index 5d674da..c7b6bc7 100644 --- a/utils/case_generate_utils/case_template.txt +++ b/utils/case_generate_utils/case_template.txt @@ -30,7 +30,10 @@ class ${class_title}Auto: source=GLOBAL_VARS) GLOBAL_VARS.update(dependence_results if dependence_results else {}) # 处理请求前的用例数据 -> 发送请求 -> 响应/数据库断言 -> 断言成功后进行参数提取 - res = RequestControl().api_request_flow(request_data=case, global_var=GLOBAL_VARS) + if GLOBAL_VARS.get("db_info"): + res = RequestControl().api_request_flow(request_data=case, global_var=GLOBAL_VARS, db_info=GLOBAL_VARS["db_info"]) + else: + res = RequestControl().api_request_flow(request_data=case, global_var=GLOBAL_VARS) GLOBAL_VARS.update(res) # 后置依赖处理 if case.get("case_dependence") and case["case_dependence"].get("teardown"): diff --git a/utils/requests_utils/request_control.py b/utils/requests_utils/request_control.py index 75c2a05..98b9115 100644 --- a/utils/requests_utils/request_control.py +++ b/utils/requests_utils/request_control.py @@ -21,6 +21,7 @@ from utils.files_utils.files_handle import get_files from utils.files_utils.yaml_handle import YamlHandle from utils.assertion_utils.assert_control import AssertHandle from utils.report_utils.allure_handle import allure_step +from utils.database_utils.mysql_handle import MysqlServer class RequestControl(BaseRequest): @@ -265,53 +266,107 @@ class RequestControl(BaseRequest): allure_step(f"响应结果: {response_result}") allure_step(f"响应耗时: {response_time_seconds} s || {response_time_millisecond} ms") - @staticmethod - def after_request(response: Response, extract): + def after_request(self, response: Response, api_data, db_info=None): """ - 从响应数据中提取请求后的参数,并保存到全局变量中 - :param response: playwright APIResponse 响应对象 - :param extract: 需要提取的参数字典 '{"k1": "$.data"}' 或 '{"k1": "data:(.*?)$"}' - :return: + 请求结束后提取参数,目前支持从响应数据、数据库、用例数据中提取 + :param response: Response 响应对象 + :param api_data: 接口数据需要提取的参数字典 '{"k1": "$.data"}' 或 '{"k1": "data:(.*?)$"}' + :return: - """ - logger.info(f"断言成功后,参数提取表达式extract: {extract}") - json_result = {} - re_result = {} - response_result = {} - if extract: - if extract.get("type_jsonpath"): - # 如果响应数据是json格式,则将按照json方式对后置提取参数进行处理 - res = response.json() - for k, v in extract["type_jsonpath"].items(): - json_result[k] = json_extractor(res, v) - logger.debug(f"--从response.json()中通过jsonpath方式提取到的结果 --> {json_result}") - if extract.get("type_re"): - # 如果响应数据是str格式,则将按照str方式对后置提取参数进行处理 - res = response.text - for k, v in extract["type_re"].items(): - re_result[k] = data_handle(obj=re_extract(res, v)) - logger.debug(f"--从response.text中通过正则表达式提取到的结果 --> {re_result} ") + """ + extract = api_data.get("extract") + logger.info(f"断言成功后需要进行提取操作,extract={extract}") - if extract.get("type_response"): - for k, v in extract["type_response"].items(): - response_result[k] = response_extract(response, v) - logger.debug(f"--从response中提取到的结果 --> {re_result}") - result = {**json_result, **re_result, **response_result} - logger.info(f"--参数提取结果extract --> {result} --") - allure_step(f"参数提取结果extract:{result}") - return result + case_results = {} + response_results = {} + database_results = {} + default_results = {} + + for k, v in extract.items(): + if k.lower() == "case": + logger.info(f"数据来源:{k}") + # 将用例数据作为来源 + for _k, _v in v.items(): + if _k.lower() == "type_jsonpath": + for i, j in _v.items(): + case_results[i] = json_extractor(api_data, j) + + elif _k.lower() == "type_re": + for i, j in _v.items(): + case_results[i] = re_extract(str(api_data), j) + else: + logger.error(f"提取方式: {_k} 错误,仅支持type_jsonpath、type_re两种") + logger.info(f"数据来源:{k}, 提取结果:{case_results} --") + elif k.lower() == "database": + logger.info(f"数据来源:{k}") + # 将数据库SQL执行结果作为来源 + if v.get("sql"): + mysql = MysqlServer(**db_info) + sql_result = mysql.query_all(v["sql"]) + v.pop("sql") + else: + sql_result = None + logger.error(f"数据库提取参数必须传入sql") + if sql_result: + for _k, _v in v.items(): + if _k.lower() == "type_jsonpath": + for i, j in _v.items(): + database_results[i] = json_extractor(sql_result, j) + + elif _k.lower() == "type_re": + for i, j in _v.items(): + database_results[i] = re_extract(str(sql_result), j) + else: + logger.error(f"提取方式: {_k} 错误,仅支持type_jsonpath、type_re两种") + logger.info(f"数据来源:{k}, 提取结果:{database_results} --") + elif k.lower() == "response": + logger.info(f"数据来源:{k}") + # 来源=response + for _k, _v in v.items(): + if _k.lower() == "type_jsonpath": + for i, j in _v.items(): + response_results[i] = json_extractor(response.json(), j) + elif _k.lower() == "type_re": + for i, j in _v.items(): + response_results[i] = re_extract(response.text, j) + elif _k.lower() == "type_response": + for i, j in _v.items(): + response_results[i] = response_extract(response, j) + else: + logger.error(f"提取方式: {_k} 错误,仅支持type_jsonpath、type_re、type_response三种") + logger.info(f"数据来源:{k}, 提取结果:{response_results} --") + else: + logger.info(f"数据来源:Response对象") + # 直接k=type_jsonpath, type_re, type_response, 来源默认是response + if k.lower() == "type_jsonpath": + for i, j in v.items(): + default_results[i] = json_extractor(response.json(), j) + elif k.lower() == "type_re": + for i, j in v.items(): + default_results[i] = re_extract(response.text, j) + elif k.lower() == "type_response": + for i, j in v.items(): + default_results[i] = response_extract(response, j) + else: + logger.error( + f"数据来源默认是Response对象, 提取方式: {k} 错误,仅支持type_jsonpath、type_re、type_response三种") + + logger.info(f"数据来源:Response对象, 提取结果:{default_results}") + + return {**case_results, **response_results, **database_results, **default_results} # -----接口请求流程:获取接口数据 -> 处理接口请求数据 -> 请求接口 -> 接口断言 -> 接口数据提取 -------------- def api_request_flow(self, request_data: dict = None, global_var: dict = None, api_file_path: str = None, - key: str = None): + key: str = None, db_info: dict = None): """ - 发送请求并进行后置参数提取操作。 + 发送请求并进行后置参数提取操作。lll request_data参数 与 api_file_path,key, 这两个必须传递其中一个 :param request_data: 请求数据字典,包含请求所需的所有信息。 :param global_var: 包含全局变量的字典,这些变量用于替换到请求数据的关键字:${} :param api_file_path: 接口所在的目录或者文件路径 :param key: 接口的ID + :param db_info: 数据库连接信息,用于数据库断言/数据库提取数据时连接数据库 :return: 接口请求数据以及从接口响应提取的参数,字典。 :raises ValueError: 如果请求数据无效或缺失。 """ @@ -345,8 +400,9 @@ class RequestControl(BaseRequest): AssertHandle(assert_data=new_api_data["assert_response"], response=response).assert_handle() # 进行响应参数提取,并保存提取后的数据 - extract_results = self.after_request(response=response, extract=new_api_data.get("extract")) - save_api_data.update(extract_results) + if new_api_data.get("extract"): + extract_results = self.after_request(response=response, api_data=new_api_data, db_info=db_info) + save_api_data.update(extract_results) # 将接口请求参数payload的值保存到save_api_data中 save_api_data.update({"_payload": new_api_data["payload"]} if new_api_data.get("payload") else {})