支持指定数据提取来源,从响应数据,用例数据,数据库中通过jsonpath和正则表达式方式提取数据
This commit is contained in:
@@ -34,7 +34,7 @@
|
|||||||
* 支持利用allure设置用例优先级,运行指定优先级的用例
|
* 支持利用allure设置用例优先级,运行指定优先级的用例
|
||||||
* 执行环境一键切换,解决多环境相互影响问题
|
* 执行环境一键切换,解决多环境相互影响问题
|
||||||
* 自动生成用例代码: 测试人员在yaml/excel文件中填写好测试用例, 程序可以直接生成用例代码,纯小白也能使用
|
* 自动生成用例代码: 测试人员在yaml/excel文件中填写好测试用例, 程序可以直接生成用例代码,纯小白也能使用
|
||||||
* 支持参数多类型提取:支持通过jsonpath从response.json提取数据;支持通过正则表达式从response.text提取数据;支持直接提取response本身的数据,例如response.cookies
|
* 支持参数多类型提取:支持从响应数据,数据库,用例数据中通过jsonpath或者正则方式提取数据
|
||||||
* 使用Allure生成测试报告,并对测试报告进行了定制化修改,使得测试报告更加美观
|
* 使用Allure生成测试报告,并对测试报告进行了定制化修改,使得测试报告更加美观
|
||||||
* 日志模块: 采用loguru管理日志,可以输出更为优雅,简洁的日志
|
* 日志模块: 采用loguru管理日志,可以输出更为优雅,简洁的日志
|
||||||
* 钉钉、企业微信通知: 支持多种通知场景,执行成功之后,可选择发送钉钉、或者企业微信、邮箱通知
|
* 钉钉、企业微信通知: 支持多种通知场景,执行成功之后,可选择发送钉钉、或者企业微信、邮箱通知
|
||||||
@@ -191,45 +191,78 @@ case_info: # 具体的用例数据,是以列表的形式进行管理
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 6. 参数提取说明
|
### 6. 参数提取说明
|
||||||
|
目前支持从响应数据(response)、数据库(database)、用例数据(case)中提取数据。
|
||||||
目前支持3种方式的参数提取:type_jsonpath, type_re, type_response
|
目前支持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:
|
extract:
|
||||||
type_jsonpath:
|
type_jsonpath:
|
||||||
nickname: $.username
|
res_j_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:
|
|
||||||
type_re:
|
type_re:
|
||||||
nickname: \"username":"(.*?)"
|
res_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:
|
|
||||||
type_response:
|
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. 断言方式
|
### 7. 断言方式
|
||||||
|
|||||||
+148
-187
@@ -17,209 +17,170 @@ ENV_VARS = {
|
|||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
# 环境相关域名
|
# 环境相关域名
|
||||||
"host": "https://******",
|
"host": "",
|
||||||
"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://******",
|
|
||||||
"wiki_host": "",
|
"wiki_host": "",
|
||||||
"pms_host": "http://******",
|
"pms_host": "",
|
||||||
|
"glcc_host": "",
|
||||||
# 获取oauth_token需要的参数
|
# 获取oauth_token需要的参数
|
||||||
"client_id": "****client_id****",
|
"client_id": "",
|
||||||
"client_secret": "****client_secret****",
|
"client_secret": "*",
|
||||||
# 万能验证码
|
# 万能验证码
|
||||||
"green_code": "******",
|
"green_code": "",
|
||||||
# 测试账号 - 普通用户(测试仓库开发者), 默认登录账号
|
# 测试账号 - 普通用户(测试仓库开发者), 默认登录账号
|
||||||
"env_login": "******",
|
"env_login": "",
|
||||||
"env_password": "******", # 运行时需要手动更改密码
|
"env_password": "", # 运行时需要手动更改密码
|
||||||
"env_nickname": "******",
|
"env_nickname": "",
|
||||||
"env_user_id": 36669,
|
"env_user_id": 0,
|
||||||
# 测试账号 - 超级管理员(测试仓库管理员)
|
|
||||||
"env_super_login": "******",
|
|
||||||
"env_super_password": "******",
|
|
||||||
"env_super_nickname": "******",
|
|
||||||
"env_super_user_id": 36661,
|
|
||||||
# 测试账号 - 普通用户(测试仓库报告者)
|
# 测试账号 - 普通用户(测试仓库报告者)
|
||||||
"t_login": "******",
|
"t_login": "",
|
||||||
"t_password": "******",
|
"t_password": "",
|
||||||
"t_nickname": "******",
|
"t_nickname": "",
|
||||||
"t_user_id": 36670,
|
"t_user_id": 0,
|
||||||
# 测试仓库 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_login": "",
|
||||||
"env_super_password": "",
|
"env_super_password": "", # 运行时需要手动更改密码
|
||||||
"env_super_user_id": 0,
|
|
||||||
# 测试仓库 env_repo_owner/env_repo_identifier
|
# 测试仓库 env_repo_owner/env_repo_identifier
|
||||||
"env_repo_owner": "",
|
"env_repo_owner": "",
|
||||||
"env_repo_identifier": "",
|
"env_repo_identifier": "",
|
||||||
"env_project_id": "",
|
"env_project_id": "",
|
||||||
# pms相关环境变量
|
# pms相关环境变量 - 产品
|
||||||
"env_pms_product_id": "",
|
"env_pms_product_id": "",
|
||||||
"env_pms_product_identifier": "",
|
"env_pms_product_identifier": "",
|
||||||
|
# pms相关环境变量 - 项目
|
||||||
"env_pms_project_id": "",
|
"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_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": "**********"
|
|
||||||
|
|
||||||
}
|
},
|
||||||
|
"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": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ class ${class_title}Auto:
|
|||||||
source=GLOBAL_VARS)
|
source=GLOBAL_VARS)
|
||||||
GLOBAL_VARS.update(dependence_results if dependence_results else {})
|
GLOBAL_VARS.update(dependence_results if dependence_results else {})
|
||||||
# 处理请求前的用例数据 -> 发送请求 -> 响应/数据库断言 -> 断言成功后进行参数提取
|
# 处理请求前的用例数据 -> 发送请求 -> 响应/数据库断言 -> 断言成功后进行参数提取
|
||||||
|
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)
|
res = RequestControl().api_request_flow(request_data=case, global_var=GLOBAL_VARS)
|
||||||
GLOBAL_VARS.update(res)
|
GLOBAL_VARS.update(res)
|
||||||
# 后置依赖处理
|
# 后置依赖处理
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ from utils.files_utils.files_handle import get_files
|
|||||||
from utils.files_utils.yaml_handle import YamlHandle
|
from utils.files_utils.yaml_handle import YamlHandle
|
||||||
from utils.assertion_utils.assert_control import AssertHandle
|
from utils.assertion_utils.assert_control import AssertHandle
|
||||||
from utils.report_utils.allure_handle import allure_step
|
from utils.report_utils.allure_handle import allure_step
|
||||||
|
from utils.database_utils.mysql_handle import MysqlServer
|
||||||
|
|
||||||
|
|
||||||
class RequestControl(BaseRequest):
|
class RequestControl(BaseRequest):
|
||||||
@@ -265,53 +266,107 @@ class RequestControl(BaseRequest):
|
|||||||
allure_step(f"响应结果: {response_result}")
|
allure_step(f"响应结果: {response_result}")
|
||||||
allure_step(f"响应耗时: {response_time_seconds} s || {response_time_millisecond} ms")
|
allure_step(f"响应耗时: {response_time_seconds} s || {response_time_millisecond} ms")
|
||||||
|
|
||||||
@staticmethod
|
def after_request(self, response: Response, api_data, db_info=None):
|
||||||
def after_request(response: Response, extract):
|
|
||||||
"""
|
"""
|
||||||
从响应数据中提取请求后的参数,并保存到全局变量中
|
请求结束后提取参数,目前支持从响应数据、数据库、用例数据中提取
|
||||||
:param response: playwright APIResponse 响应对象
|
:param response: Response 响应对象
|
||||||
:param extract: 需要提取的参数字典 '{"k1": "$.data"}' 或 '{"k1": "data:(.*?)$"}'
|
:param api_data: 接口数据需要提取的参数字典 '{"k1": "$.data"}' 或 '{"k1": "data:(.*?)$"}'
|
||||||
:return:
|
:return:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
logger.info(f"断言成功后,参数提取表达式extract: {extract}")
|
extract = api_data.get("extract")
|
||||||
json_result = {}
|
logger.info(f"断言成功后需要进行提取操作,extract={extract}")
|
||||||
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} ")
|
|
||||||
|
|
||||||
if extract.get("type_response"):
|
case_results = {}
|
||||||
for k, v in extract["type_response"].items():
|
response_results = {}
|
||||||
response_result[k] = response_extract(response, v)
|
database_results = {}
|
||||||
logger.debug(f"--从response中提取到的结果 --> {re_result}")
|
default_results = {}
|
||||||
result = {**json_result, **re_result, **response_result}
|
|
||||||
logger.info(f"--参数提取结果extract --> {result} --")
|
for k, v in extract.items():
|
||||||
allure_step(f"参数提取结果extract:{result}")
|
if k.lower() == "case":
|
||||||
return result
|
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,
|
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, 这两个必须传递其中一个
|
request_data参数 与 api_file_path,key, 这两个必须传递其中一个
|
||||||
|
|
||||||
:param request_data: 请求数据字典,包含请求所需的所有信息。
|
:param request_data: 请求数据字典,包含请求所需的所有信息。
|
||||||
:param global_var: 包含全局变量的字典,这些变量用于替换到请求数据的关键字:${}
|
:param global_var: 包含全局变量的字典,这些变量用于替换到请求数据的关键字:${}
|
||||||
:param api_file_path: 接口所在的目录或者文件路径
|
:param api_file_path: 接口所在的目录或者文件路径
|
||||||
:param key: 接口的ID
|
:param key: 接口的ID
|
||||||
|
:param db_info: 数据库连接信息,用于数据库断言/数据库提取数据时连接数据库
|
||||||
:return: 接口请求数据以及从接口响应提取的参数,字典。
|
:return: 接口请求数据以及从接口响应提取的参数,字典。
|
||||||
:raises ValueError: 如果请求数据无效或缺失。
|
:raises ValueError: 如果请求数据无效或缺失。
|
||||||
"""
|
"""
|
||||||
@@ -345,7 +400,8 @@ class RequestControl(BaseRequest):
|
|||||||
AssertHandle(assert_data=new_api_data["assert_response"], response=response).assert_handle()
|
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"))
|
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)
|
save_api_data.update(extract_results)
|
||||||
|
|
||||||
# 将接口请求参数payload的值保存到save_api_data中
|
# 将接口请求参数payload的值保存到save_api_data中
|
||||||
|
|||||||
Reference in New Issue
Block a user