1. 全局梳理各模块导包方式,优化代码样式 2. 修改reamd文件,将详细功能说明使用外链方式打开查看 3. 增加用例,测试框架支持多域名情况
This commit is contained in:
473
README.md
473
README.md
@@ -42,13 +42,13 @@
|
||||
├────case_utils/ 测试框架相关工具类
|
||||
│ ├────__init__.py
|
||||
│ ├────allure_handle.py 操作allure的相关方法
|
||||
│ ├────platform_handle.py 跨平台的支持allure,用于生成allure测试报告
|
||||
│ ├────assert_handle.py 断言处理, 包括响应断言和数据库断言
|
||||
│ ├────case_fun_handle.py 根据配置文件,从指定类型文件中读取用例数据,并调用生成用例文件方法,生成用例文件
|
||||
│ ├────case_data_analysis 分析用例数据是否符合规范
|
||||
│ ├────case_fun_handle.py 根据配置文件,从指定类型文件中读取用例数据,并调用生成用例文件方法,生成用例文件
|
||||
│ ├────data_handle.py 数据处理
|
||||
│ ├────request_data_handle.py 针对用例数据进行请求前后的处理
|
||||
│ ├────get_results_handle.py 从pytest-html/allure测试报告中获取测试结果
|
||||
│ ├────platform_handle.py 跨平台的支持allure,用于生成allure测试报告
|
||||
│ ├────request_data_handle.py 针对用例数据进行请求前后的处理
|
||||
│ └────send_result_handle.py 根据配置文件,从html测试报告中获取测试结果,发送指定类型的通知
|
||||
├────common_utils/ 公共的工具类
|
||||
│ ├────__init__.py
|
||||
@@ -58,16 +58,24 @@
|
||||
│ ├────excel_handle.py 处理excel
|
||||
│ ├────files_handle.py 处理文件相关操作
|
||||
│ ├────func_handle.py 函数装饰器
|
||||
│ ├────http_server.py 封装的HTTP服务
|
||||
│ ├────mysql_handle.py 使用pymysql模块连接mysql数据库的公共方法
|
||||
│ ├────time_handle.py 封装处理时间操作的一些方法
|
||||
│ ├────wechat_handle.py 封装企业微信机器人
|
||||
│ ├────yagmail_handle.py 封装通过yagmail发送邮件的方法
|
||||
│ ├────time_handle.py 封装处理时间操作的一些方法
|
||||
│ └────yaml_handle.py 处理yaml文件
|
||||
├────config/
|
||||
│ ├────__init__.py
|
||||
│ ├────allure_config/
|
||||
│ │ ├────gitlinklogo.jpg 保存用来替换allure报告的logo的,在代码中无用处
|
||||
│ │ ├────http_server.exe http服务,用来放置在allure压缩包中,方便在不安装allure环境下打开allure报告
|
||||
│ │ ├────logo.svg 保存用来替换allure报告的logo的,在代码中无用处
|
||||
│ │ ├────双击打开Allure报告.bat .bat文件,用来放置在allure压缩包中,方便在不安装allure环境下打开allure报告
|
||||
│ ├────pytest_html_config/
|
||||
│ │ ├────pytest_html_report.css 改变pytest-html测试报告的样式文件
|
||||
│ ├────case_template.txt 自动生成的测试用例文件模板
|
||||
│ ├────global_vars.py 保存的一些全局变量
|
||||
│ ├────project_path.py 项目路径管理
|
||||
│ ├────report.css 优化html测试报告的样式文件
|
||||
│ ├────path_config.py 项目路径管理
|
||||
│ └────settings.py 配置文件
|
||||
├────conftest.py
|
||||
├────data/ 测试用例数据
|
||||
@@ -84,11 +92,11 @@
|
||||
├────run.py 运行入口
|
||||
└────test_case/ 测试用例
|
||||
│ ├────conftest.py
|
||||
│ ├────test_auto_case/
|
||||
│ ├────test_auto_case/ 自动生成的测试用例目录
|
||||
│ │ ├────test_login_demo.py
|
||||
│ │ ├────test_login_excel_demo.py
|
||||
│ │ └────test_new_project_demo.py
|
||||
│ └────test_manual_case/
|
||||
│ └────test_manual_case/ 手动编写的测试用例目录
|
||||
│ │ ├────__init__.py
|
||||
│ │ ├────test_demo.py
|
||||
│ │ └────test_login_demo.py
|
||||
@@ -212,7 +220,7 @@ excel表单2名称是:示例模块
|
||||
测试用例类:TestDemoSlmkAuto
|
||||
测试用例方法:test_demo_slmk_auto
|
||||
|
||||
## 六、运行自动化测试
|
||||
## 七、运行自动化测试
|
||||
### 1. 激活已存在的虚拟环境
|
||||
- (如果不存在会创建一个):pipenv shell (必须在项目根目录下执行)
|
||||
|
||||
@@ -227,7 +235,7 @@ excel表单2名称是:示例模块
|
||||
注意:
|
||||
- 如果pycharm.interpreter拥有了框架所需的所有依赖包,可以通过pycharm直接在`run.py`中右键运行
|
||||
|
||||
## 七、查看测试报告
|
||||
## 八、查看测试报告
|
||||
### pytest-html测试报告
|
||||
如果是pytest-html生成的测试报告,直接打开`outputs`目录下的`.html`报告即可。支持通过任意浏览器打开查看
|
||||
|
||||
@@ -240,448 +248,31 @@ excel表单2名称是:示例模块
|
||||
- 如果通过点击`outputs/report/allure_html/双击打开Allure报告.bat`打开测试报告,命令窗口显示乱码,或者打不开,可以把`.bat`的文件名称修改为英文的名称,里面的所有中文注释全部移除,再次尝试
|
||||
|
||||
|
||||
## 八 、详细功能说明
|
||||
### 1. 用例中如何生成随机数据
|
||||
在测试过程中,可能涉及到一些特殊场景,需要生成定制化的数据。每次运行测试,都需要按照指定规则随机生成。
|
||||
例如:`data/test_new_project_demo.yaml` 中payload.name就是使用Faker随机生成的。
|
||||
我这里写了一个表达式:`${faker.name().replace(" ", "").replace(".", "")}`
|
||||
- 在测试方法中`case_data = RequestPreDataHandle(case).request_data_handle()`会进行用例数据处理
|
||||
- 处理过程中会调用`common_utils.data_handle.data_replace`进行数据处理
|
||||
- 在`common_utils.data_handle `有导入Faker包,并且初始化了faker对象。因此上述表达式能成功运行获取其结果
|
||||
## 九 、详细功能说明
|
||||
- [如何实现动态数据的热加载?](https://www.gitlink.org.cn/zone/tester/newdetail/204)
|
||||
|
||||
这里需要注意以下几点:
|
||||
- 如果是python自带的一些方法,不需要额外导包,或者写方法,就会直接处理。
|
||||
- Faker这个Python库,已经可以满足生成各种各样的伪数据,这个我已经在`common_utils.data_handle `中定义好了。
|
||||
- 如果还有一些其他的定制化数据,可以在`common_utils.data_handle `中进行添加。
|
||||
- [如何提取响应数据作为全局变量并使用?](https://www.gitlink.org.cn/zone/tester/newdetail/205)
|
||||
|
||||
### 2. 用例中如何提取响应数据作为全局变量并使用
|
||||
在测试过程中,通常下一个接口需要用到上一个接口的响应数据,这个时候就涉及到参数的提取。
|
||||
我们在用例数据中定义了参数:`extract`进行后置参数的提取,根据接口返回数据的类型(JSON或者Text)采取不同的方法,从响应数据中提取参数,保存在全局变量中。
|
||||
例如:
|
||||
- 登录接口中定义了需要提取的参数:`data/test_login_demo.yaml`
|
||||
```yaml
|
||||
extract:
|
||||
nickname: $.username
|
||||
login: $.login
|
||||
user_id: $.user_id
|
||||
```
|
||||
- 请求结束后,`case_utils/request_data_handle.py.after_request_extract`就会接口返回数据的类型(JSON或者Text)采取不同的方法,从响应数据中提取参数,保存在全局变量中。
|
||||
- 下一个接口需要用到user_id,只需要在用例中以如下格式书写`${user_id}`即可。
|
||||
```yaml
|
||||
payload:
|
||||
"user_id": ${user_id}
|
||||
"name": ${faker.name().replace(" ", "").replace(".", "")}
|
||||
"repository_name": ${faker.name().replace(" ", "").replace(".", "")}
|
||||
```
|
||||
- [如何进行响应数据断言?](https://www.gitlink.org.cn/zone/tester/newdetail/206)
|
||||
|
||||
### 3. 如何进行响应数据断言
|
||||
以下是支持的几种响应断言:
|
||||
| 断言方式 | 说明 |
|
||||
| ------------ | ------------ |
|
||||
| eq | 相等,判断预期结果是否等于实际结果 |
|
||||
| in | 包含, 判断实际结果是否包含预期结果 |
|
||||
| gt | 大于, 判断预期结果是否大于实际结果 |
|
||||
| lt | 小于, 判断预期结果是否小于实际结果 |
|
||||
| not | 非,判断预期结果不等于实际结果 |
|
||||
- [如何进行数据库断言?](https://www.gitlink.org.cn/zone/tester/newdetail/207)
|
||||
|
||||
以下是响应断言示例:
|
||||
```yaml
|
||||
assert_response:
|
||||
eq:
|
||||
http_code: 200
|
||||
$.user_id: ${user_id}
|
||||
in:
|
||||
$.login: ${login}
|
||||
gt:
|
||||
$.user_id: 84955
|
||||
lt:
|
||||
$.user_id: 84953
|
||||
not:
|
||||
$.user_id: 85390
|
||||
```
|
||||
- 预期结果:http_code;实际结果:200; 会从接口获取响应码,判断预期结果是否等于实际结果。
|
||||
- 预期结果:`$.user_id`, 实际结果:`${user_id}`; 会从接口响应数据中通过表达式`$.user_id`提取user_id作为预期结果, 从全局变量中替换变量`${user_id}`获取user_id作为实际结果,判断预期结果是否等于实际结果。
|
||||
- 预期结果:`$.login`, 实际结果:`${login}`; 会从接口响应数据中通过表达式`$.login`提取login作为预期结果, 从全局变量中替换变量`${login}`获取login作为实际结果,判断实际结果是否包含预期结果。
|
||||
- 预期结果:`$.user_id`, 实际结果:84955; 会从接口响应数据中通过表达式`$.user_id`提取user_id作为预期结果,判断预期结果是否大于实际结果。
|
||||
- 预期结果:`$.user_id`, 实际结果:84953; 会从接口响应数据中通过表达式`$.user_id`提取user_id作为预期结果,判断预期结果是否小于实际结果。
|
||||
- 预期结果:`$.user_id`, 实际结果:85390; 会从接口响应数据中通过表达式`$.user_id`提取user_id作为预期结果,判断预期结果是否不等于实际结果。
|
||||
- [如何配置邮箱通知?](https://www.gitlink.org.cn/zone/tester/newdetail/208)
|
||||
|
||||
- [如何配置钉钉通知?](https://www.gitlink.org.cn/zone/tester/newdetail/209)
|
||||
|
||||
### 4. 如何进行数据库断言
|
||||
以下是支持的几种数据库断言:
|
||||
| 断言方式 | 说明 |
|
||||
| ------------ | ------------ |
|
||||
| len | 数据库SQL查询结果的数量 是否 等于预期结果 |
|
||||
| eq | 从数据库SQL查询结果中通过jsonpath表达式提取值,判断是否等于预期结果 |
|
||||
|...... | 其他断言方式待扩展 |
|
||||
- [如何配置企业微信通知?](https://www.gitlink.org.cn/zone/tester/newdetail/210)
|
||||
|
||||
以下是数据库断言示例-1:
|
||||
```yaml
|
||||
assert_sql:
|
||||
eq:
|
||||
sql: select count(*) from tokens where user_id=${user_id};
|
||||
len: 1
|
||||
```
|
||||
- sql表示需要查询的SQL, 这里调用的是`common_utils/mysql_handle.py.MysqlServer.query_one`, 返回的数据类型是字典。
|
||||
- len:1, 判断的是查询结果的个数是否等于1.
|
||||
- 该场景一般用于某操作往数据库中插入了一条数据,判断是否插入成功,而不需要去校验其数据准确性。
|
||||
- 例如上述数据库断言示例中,我是去查询tokens中是否存在指定user_id的数据,其实际场景是只要登录成功,就会往token表里面插入登录用户的token。因此要判断实际是否登录成功,只需要判断表里面有没有针对该用户插入一条数据即可。
|
||||
- [如何测试上传文件接口?](https://www.gitlink.org.cn/zone/tester/newdetail/211)
|
||||
|
||||
- [如何处理同一环境存在多域名的情况?](https://www.gitlink.org.cn/zone/tester/newdetail/214)
|
||||
|
||||
以下是数据库断言示例-2:
|
||||
```yaml
|
||||
assert_sql:
|
||||
eq:
|
||||
sql: select id, `name`, identifier from projects where user_id=${user_id} ORDER BY created_on DESC;
|
||||
$.id: ${project_id}
|
||||
$.name: ${project_name}
|
||||
$.identifier: ${project_identifier}
|
||||
```
|
||||
- sql表示需要查询的SQL, 这里调用的是`common_utils/mysql_handle.py.MysqlServer.query_one`, 返回的数据类型是字典。
|
||||
- 这里是在projects表里面查询指定用户创建的项目信息(id, `name`, identifier),并按创建时间倒序排序。
|
||||
- 预期结果:`$.id`, 实际结果:`${project_id}`, 从数据库查询结果中通过表达式`$.id`提取id作为实际结果, 从全局变量中替换变量`${project_id}`获取project_id作为实际结果,判断预期结果是否等于实际结果。
|
||||
- 预期结果:`$.name`, 实际结果:`${project_name}`, 从数据库查询结果中通过表达式`$.name`提取name作为实际结果, 从全局变量中替换变量`${project_name}`获取project_name作为实际结果,判断预期结果是否等于实际结果。
|
||||
- 预期结果:`$.identifier`, 实际结果:`${project_identifier}`, 从数据库查询结果中通过表达式`$.identifier`提取identifier作为实际结果, 从全局变量中替换变量`${project_identifier}`获取project_identifier作为实际结果,判断预期结果是否等于实际结果。
|
||||
|
||||
注意:
|
||||
- 关于数据库断言,需要考虑实际使用场景,来综合考虑调整。这里我考虑的可能还有局限性。欢迎大家来反馈。
|
||||
- 另外,其实sql有很大程度影响数据库断言的走向, 我们写sql的时候尽量写的精准一些。
|
||||
|
||||
### 5. 配置邮箱通知
|
||||
- 首先我们需要在配置文件`config/settings.py`中选择邮件发送方式:SEND_RESULT_TYPE = 3
|
||||
- 获取邮件的相关信息,并填写到配置文件`config/settings.py`中。这些配置信息可以从邮箱设置中获取。不知道如何配置的,可以直接互联网上搜索。
|
||||
|
||||
```python
|
||||
# 发送邮件的相关配置信息
|
||||
email = {
|
||||
"user": "******", # 发件人邮箱
|
||||
"password": "******", # 发件人邮箱授权码/发件人邮箱密码
|
||||
"host": "smtp.qq.com",
|
||||
"to": ["******", "******"] # 收件人邮箱
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- 在配置文件`config/settings.py`中配置邮件发送的标题以及内容。
|
||||
注意:
|
||||
1)以下`${变量名}`是已经定义好的。只能减,不能增。
|
||||
2)邮件标题以及内容也可自行调整。
|
||||
|
||||
```python
|
||||
# ------------------------------------ 邮件通知内容 ----------------------------------------------------#
|
||||
email_subject = f"接口自动化报告"
|
||||
email_content = """
|
||||
各位同事, 大家好:
|
||||
|
||||
自动化用例于 <strong>${start_time} </strong> 开始运行,运行时长:<strong>${run_time} s</strong>, 目前已执行完成。
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
测试人:<strong> ${tester} </strong>
|
||||
所属部门:<strong> ${department} </strong>
|
||||
项目环境:<strong> ${run_env} </strong>
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
执行结果如下:
|
||||
用例运行总数:<strong> ${total} 个</strong>
|
||||
通过用例个数(passed): <strong><font color="green" >${passed} 个</font></strong>
|
||||
失败用例个数(failed): <strong><font color="red" >${failed} 个</font></strong>
|
||||
异常用例个数(error): <strong><font color="orange" >${broken} 个</font></strong>
|
||||
跳过用例个数(skipped): <strong><font color="grey" >${skipped} 个</font></strong>
|
||||
失败重试用例个数 * 次数之和(rerun): <strong>${rerun} 个</strong>
|
||||
成 功 率:<strong> <font color="green" >${pass_rate} %</font></strong>
|
||||
|
||||
**********************************
|
||||
附件为具体的测试报告,详细情况可下载附件查看, 非相关负责人员可忽略此消息。谢谢。
|
||||
"""
|
||||
```
|
||||
|
||||
|
||||
### 6. 配置钉钉通知
|
||||
- 首先我们需要在配置文件`config/settings.py`中选择钉钉发送方式:SEND_RESULT_TYPE = 1
|
||||
- 获取钉钉的相关信息,并填写到配置文件`config/settings.py`中。具体可以参考:[钉钉机器人](https://blog.csdn.net/FloraCHY/article/details/130618777?spm=1001.2014.3001.5502 "钉钉机器人")
|
||||
|
||||
```python
|
||||
# ------------------------------------ 钉钉相关配置 ----------------------------------------------------#
|
||||
ding_talk = {
|
||||
"webhook_url": "https://oapi.dingtalk.com/robot/send?access_token=***********",
|
||||
"secret": "***********"
|
||||
}
|
||||
|
||||
```
|
||||
- 在配置文件`config/settings.py`中配置钉钉发送的标题以及内容。
|
||||
注意:
|
||||
1)以下`${变量名}`是已经定义好的。只能减,不能增。
|
||||
2)邮件标题以及内容也可自行调整。
|
||||
```python
|
||||
# ------------------------------------ 钉钉通知内容 ----------------------------------------------------#
|
||||
ding_talk_title = f"接口自动化报告"
|
||||
ding_talk_content = """
|
||||
各位同事, 大家好:
|
||||
|
||||
### 自动化用例于 ${start_time} 开始运行,运行时长:${run_time} s, 目前已执行完成。
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
#### 测试人: ${tester}
|
||||
#### 所属部门: ${department}
|
||||
#### 项目环境: ${run_env}
|
||||
---------------------------------------------------------------------------------------------------------------
|
||||
#### 执行结果如下:
|
||||
- 用例运行总数: ${total} 个
|
||||
- 通过用例个数(passed): ${passed} 个
|
||||
- 失败用例个数(failed): ${failed} 个
|
||||
- 异常用例个数(error): ${broken} 个
|
||||
- 跳过用例个数(skipped): ${skipped} 个
|
||||
- 失败重试用例个数 * 次数之和(rerun): ${rerun} 个
|
||||
- 成 功 率: ${pass_rate} %
|
||||
|
||||
**********************************
|
||||
附件为具体的测试报告,详细情况可下载附件查看, 非相关负责人员可忽略此消息。谢谢。
|
||||
"""
|
||||
```
|
||||
|
||||
|
||||
### 7. 配置企业微信通知
|
||||
- 首先我们需要在配置文件`config/settings.py`中选择企业微信发送方式:SEND_RESULT_TYPE = 2
|
||||
- 获取企业微信的相关信息,并填写到配置文件`config/settings.py`中。具体可以参考:[企业微信](https://blog.csdn.net/FloraCHY/article/details/130624354?spm=1001.2014.3001.5502 "企业微信")
|
||||
```python
|
||||
# ------------------------------------ 企业微信相关配置 ----------------------------------------------------#
|
||||
wechat = {
|
||||
"webhook_url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=********",
|
||||
}
|
||||
```
|
||||
- 在配置文件`config/settings.py`中配置企业微信发送内容。
|
||||
注意:
|
||||
1)以下`${变量名}`是已经定义好的。只能减,不能增。
|
||||
2)邮件标题以及内容也可自行调整。
|
||||
|
||||
```python
|
||||
# ------------------------------------ 企业微信通知内容 ----------------------------------------------------#
|
||||
wechat_content = """
|
||||
各位同事, 大家好:
|
||||
|
||||
### 自动化用例于 ${start_time} 开始运行,运行时长:${run_time} s, 目前已执行完成。
|
||||
--------------------------------
|
||||
#### 测试人: ${tester}
|
||||
#### 所属部门: ${department}
|
||||
#### 项目环境: ${run_env}
|
||||
--------------------------------
|
||||
#### 执行结果如下:
|
||||
- 用例运行总数: ${total} 个
|
||||
- 通过用例个数(passed):<font color=\"info\"> ${passed} 个</font>
|
||||
- 失败用例个数(failed): <font color=\"warning\"> ${failed} 个</font>
|
||||
- 异常用例个数(error): <font color=\"warning\"> ${broken} 个</font>
|
||||
- 跳过用例个数(skipped): <font color=\"comment\"> ${skipped} 个</font>
|
||||
- 失败重试用例个数 * 次数之和(rerun): <font color=\"comment\"> ${rerun} 个</font>
|
||||
- 成 功 率: <font color=\"info\"> ${pass_rate} % </font>
|
||||
|
||||
**********************************
|
||||
附件为具体的测试报告,详细情况可下载附件查看, 非相关负责人员可忽略此消息。谢谢。
|
||||
"""
|
||||
|
||||
```
|
||||
|
||||
### 7. 上传文件接口支持
|
||||
#### 熟悉接口
|
||||
- 确定上传文件接口的URL
|
||||
- 确定上传文件接口的METHOD
|
||||
- 确定上传文件接口请求头里面的Content-Type, 我这边调试的接口都是:multipart/form-data;
|
||||
- 确定上传文件接口请求参数, 我调试的接口有两种参数形式:
|
||||
|
||||
```python
|
||||
# 第一种
|
||||
file: 文件二进制内容
|
||||
|
||||
|
||||
# 第二种
|
||||
file: 文件二进制内容
|
||||
language: zh
|
||||
```
|
||||
#### 文件上传的逻辑
|
||||
`common_utils/base_request.py` 中封装的request请求,是使用`from requests_toolbelt import MultipartEncoder`进行文件上传的。
|
||||
|
||||
- 针对单文件上传,我们需要传递一个字典,参考如下:
|
||||
```python
|
||||
field = {
|
||||
{
|
||||
'file': (filename, file_content), # file是接口中文件参数的名称, filename是文件名,file_content是文件二进制内容
|
||||
"key": v # 这里是文件上传的其他参数
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- 针对多文件上传,我们需要传递一个列表嵌套元祖,参考如下:
|
||||
```python
|
||||
field =[
|
||||
('file', (filename, file_content)), # file是接口中文件参数的名称, filename是文件名,file_content是文件二进制内容
|
||||
('file', (filename, file_content)), # 这里是文件上传的其他参数
|
||||
(k, v)
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
#### 上传文件,不带其他参数
|
||||
- 我们需要设置: request_type=file
|
||||
- 然后在files中按照如下格式书写:{接口中文件参数的名称:"文件路径地址"/["文件地址1", "文件地址2"]}
|
||||
|
||||
- 参考如下:
|
||||
|
||||
```yaml
|
||||
# 公共参数
|
||||
case_common:
|
||||
allure_epic: GitLink接口(手动编写用例)
|
||||
allure_feature: 上传文件模块
|
||||
allure_story: 上传文件
|
||||
|
||||
# 用例数据
|
||||
case_upload_demo_01:
|
||||
feature: 上传文件
|
||||
title: 测试单文件上传
|
||||
run: True
|
||||
url: /api/attachments.json
|
||||
method: POST
|
||||
headers:
|
||||
cookies: ${login_cookie}
|
||||
cookies:
|
||||
request_type: file
|
||||
payload:
|
||||
files:
|
||||
file: TOC出库订单导入模板(2).xlsx # 此处file对应接口中文件参数的名称
|
||||
extract:
|
||||
file_id: $.id
|
||||
assert_response:
|
||||
eq:
|
||||
http_code: 200
|
||||
assert_sql:
|
||||
|
||||
case_upload_demo_02:
|
||||
feature: 上传文件
|
||||
title: 测试多文件上传(该接口不支持多文件上传,这是一个示例)
|
||||
run: False
|
||||
url: /api/attachments.json
|
||||
method: POST
|
||||
headers:
|
||||
cookies: ${login_cookie}
|
||||
cookies:
|
||||
request_type: file
|
||||
payload:
|
||||
files:
|
||||
file:
|
||||
- 导入TOC订单.xls
|
||||
- toc.xls
|
||||
extract:
|
||||
file_id: $.id
|
||||
assert_response:
|
||||
eq:
|
||||
http_code: 200
|
||||
assert_sql:
|
||||
```
|
||||
|
||||
#### 上传文件,带其他参数
|
||||
- 我们需要设置: request_type=file
|
||||
- 然后在files中按照如下格式书写:{接口中文件参数的名称:"文件路径地址"/["文件地址1", "文件地址2"]}
|
||||
- 由于请求参数里面还传递了`language:zh`, 因此我们需要写在`payload`中
|
||||
- 在`common_utils/base_request.py` 中,我们会将`language:zh`以元祖形式处理到files里面
|
||||
|
||||
- 参考如下:
|
||||
|
||||
```yaml
|
||||
# 公共参数
|
||||
case_common:
|
||||
allure_epic: OWMS系统(自动生成用例) # 敏捷里面的概念,定义史诗,相当于module级的标签, 往下是 feature
|
||||
allure_feature: 出库模块 # 功能点的描述,相当于class级的标签, 理解成模块往下是 story
|
||||
allure_story: TOC扫描签出接口 # 故事,可以理解为场景,相当于method级的标签, 往下是 title
|
||||
|
||||
# 用例数据
|
||||
case_import_toc_01:
|
||||
feature: OMS系统
|
||||
title: 导入TOC订单(01)
|
||||
run: True
|
||||
url: /oms/retailGoodsTmp/selfImportExcel
|
||||
method: POST
|
||||
headers:
|
||||
Cookietoken: ${oms_cookieToken}
|
||||
request_type: file
|
||||
payload:
|
||||
language: zh
|
||||
files:
|
||||
file: TOC出库订单导入模板(2).xlsx
|
||||
extract:
|
||||
assert_response:
|
||||
eq:
|
||||
$.msg: 成功
|
||||
assert_sql:
|
||||
|
||||
case_import_toc_02:
|
||||
feature: OMS系统
|
||||
title: 导入TOC订单(02)
|
||||
run: True
|
||||
url: /oms/retailGoodsTmp/selfImportExcel
|
||||
method: POST
|
||||
headers:
|
||||
Cookietoken: ${oms_cookieToken}
|
||||
request_type: file
|
||||
payload:
|
||||
language: zh
|
||||
files:
|
||||
file:
|
||||
- 导入TOC订单.xls
|
||||
- toc.xls
|
||||
extract:
|
||||
assert_response:
|
||||
eq:
|
||||
$.msg: 成功
|
||||
assert_sql:
|
||||
```
|
||||
- [如何处理同一套框架测试多套环境的情况?](https://www.gitlink.org.cn/zone/tester/newdetail/215)
|
||||
|
||||
|
||||
|
||||
## 十、初始化项目可能遇到的问题
|
||||
- [测试机安装的是python3.7,但是本框架要求3.9.5,怎么办?](https://www.gitlink.org.cn/zone/tester/newdetail/212)
|
||||
|
||||
## 初始化项目可能遇到的问题
|
||||
### 1. 测试机安装的是python3.7,但是本框架要求3.9.5,怎么办?
|
||||
方法一:建议采纳此方法
|
||||
1)首先在项目根目录下打开命令窗口,移除虚拟环境:pipenv --rm
|
||||
2)安装虚拟环境时忽略锁定的版本号,同时安装依赖包:pipenv install --skip-lock
|
||||
如果使用上述命令报错:Warning: Python 3.9 was not found on your system... Neither 'pyenv' nor 'asdf' could be found to install Python.
|
||||
请使用如下命令:pipenv install --python 3.7 --skip-lock (注意:这里的版本号,如果你的是3.8,就应该如下写命令:pipenv install --python 3.8 --skip-lock)
|
||||
- [无法安装依赖包或者安装很慢,怎么办?](https://www.gitlink.org.cn/zone/tester/newdetail/213)
|
||||
|
||||
3)激活虚拟环境:pipenv shell
|
||||
|
||||
4)运行框架:python run.py
|
||||
|
||||
<br/>
|
||||
|
||||
方法二:
|
||||
1)首先在项目根目录下打开命令窗口,移除虚拟环境:pipenv --rm
|
||||
2)更改项目根目录下的Pipfile文件
|
||||
```
|
||||
# 如下所示,3.9更改为3.7
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
```
|
||||
3)更改项目根目录下的Pipfile.lock文件
|
||||
```
|
||||
# 如下所示,3.9更改为3.7
|
||||
"requires": {
|
||||
"python_version": "3.7"
|
||||
},
|
||||
```
|
||||
4)安装虚拟环境,同时安装依赖包:pipenv install
|
||||
|
||||
5)激活虚拟环境:pipenv shell
|
||||
|
||||
6)运行框架:python run.py
|
||||
|
||||
### 2. 无法安装依赖包或者安装很慢,怎么办?
|
||||
检查一下Pipfile文件中的pip的安装源(位置:Pipfile)
|
||||
以下安装源均可:
|
||||
```
|
||||
pip默认的镜像地址是:https://pypi.org/simple
|
||||
清华大学:https://pypi.tuna.tsinghua.edu.cn/simple 清华大学的pip源是官网pypi的镜像,每隔5分钟同步一次,重点推荐!!!
|
||||
|
||||
阿里云:http://mirrors.aliyun.com/pypi/simple/
|
||||
|
||||
中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
|
||||
|
||||
华中理工大学:http://pypi.hustunique.com/
|
||||
|
||||
山东理工大学:http://pypi.sdutlinux.org/
|
||||
|
||||
豆瓣:http://pypi.douban.com/simple/
|
||||
```
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
import json
|
||||
import allure
|
||||
from config.models import AllureAttachmentType
|
||||
import os
|
||||
from config.models import AllureAttachmentType
|
||||
|
||||
|
||||
def allure_title(title: str) -> None:
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
# @Software: PyCharm
|
||||
# @Desc: 断言
|
||||
|
||||
from case_utils.allure_handle import allure_step
|
||||
from loguru import logger
|
||||
from requests import Response
|
||||
from case_utils.data_handle import json_extractor, re_extract
|
||||
from loguru import logger
|
||||
from case_utils.request_data_handle import response_type
|
||||
from case_utils.allure_handle import allure_step
|
||||
from common_utils.mysql_handle import MysqlServer
|
||||
|
||||
|
||||
@@ -48,7 +48,8 @@ def assert_response(response: Response, expected: dict) -> None:
|
||||
actual = re_extract(response.text, _k)
|
||||
index += 1
|
||||
logger.info(f'第{index}个响应断言 -|- 预期结果: {_k}: {_v}, {type(_v)} {k} 实际结果: {actual}, {type(actual)}')
|
||||
allure_step(step_title=f'第{index}个响应断言数据---->预期结果: {_k}: {_v}, {type(_v)} {k} 实际结果: {actual}, {type(actual)}')
|
||||
allure_step(
|
||||
step_title=f'第{index}个响应断言数据---->预期结果: {_k}: {_v}, {type(_v)} {k} 实际结果: {actual}, {type(actual)}')
|
||||
try:
|
||||
if k == "eq": # 预期结果 = 实际结果
|
||||
assert _v == actual
|
||||
@@ -71,7 +72,8 @@ def assert_response(response: Response, expected: dict) -> None:
|
||||
content='目前仅支持如下关键字:eq, in, gt, lt, not')
|
||||
except AssertionError:
|
||||
logger.error(f"第{index}个响应断言失败 -|- 预期结果: {_k}: {_v}, {type(_v)} {k} 实际结果: {actual}, {type(actual)}")
|
||||
allure_step(step_title=f'第{index}个响应断言失败---->预期结果: {_k}: {_v}, {type(_v)} {k} 实际结果: {actual}, {type(actual)}')
|
||||
allure_step(
|
||||
step_title=f'第{index}个响应断言失败---->预期结果: {_k}: {_v}, {type(_v)} {k} 实际结果: {actual}, {type(actual)}')
|
||||
logger.info('\n-------------End:响应断言--------------------\n' \
|
||||
"=====================================================")
|
||||
raise AssertionError(
|
||||
|
||||
@@ -5,19 +5,18 @@
|
||||
# @Software: PyCharm
|
||||
# @Desc:
|
||||
|
||||
from config.path_config import DATA_DIR, CASE_TEMPLATE_DIR, AUTO_CASE_DIR
|
||||
from common_utils.excel_handle import ExcelHandle
|
||||
from common_utils.yaml_handle import YamlHandle
|
||||
from config.models import CaseFileType
|
||||
from config.settings import CASE_FILE_TYPE
|
||||
from loguru import logger
|
||||
from common_utils.files_handle import get_files
|
||||
from case_utils.case_data_analysis import CaseDataCheck
|
||||
import os
|
||||
from config.path_config import AUTO_CASE_DIR
|
||||
from string import Template
|
||||
import datetime
|
||||
from xpinyin import Pinyin # 纯 Python 编写的中文字符串拼音转换模块,不需要依赖外部程序和词库。
|
||||
from loguru import logger
|
||||
from common_utils.excel_handle import ExcelHandle
|
||||
from common_utils.yaml_handle import YamlHandle
|
||||
from common_utils.files_handle import get_files
|
||||
from config.models import CaseFileType
|
||||
from config.settings import CASE_FILE_TYPE
|
||||
from config.path_config import DATA_DIR, CASE_TEMPLATE_DIR, AUTO_CASE_DIR
|
||||
from case_utils.case_data_analysis import CaseDataCheck
|
||||
|
||||
"""
|
||||
主要步骤:
|
||||
@@ -162,7 +161,3 @@ def gen_case_file(filename, case_template_path, case_common, case_data, target_c
|
||||
# 将测试用例方法写入py文件中
|
||||
with open(os.path.join(target_case_path, func_name + '.py'), "w", encoding="utf-8") as fp:
|
||||
fp.write(my_case)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
generate_cases()
|
||||
|
||||
@@ -1,137 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Version: Python 3.9
|
||||
# @Time : 2023/1/12 15:22
|
||||
# @Author : chenyinhua
|
||||
# @File : case_handle.py
|
||||
# @Software: PyCharm
|
||||
# @Desc: 生成测试用例文件并返回用例数据
|
||||
|
||||
import os
|
||||
from config.path_config import CASE_TEMPLATE_DIR, DATA_DIR, AUTO_CASE_DIR
|
||||
from common_utils.excel_handle import ExcelHandle
|
||||
from common_utils.yaml_handle import YamlHandle
|
||||
from config.models import CaseFileType
|
||||
from config.settings import CASE_FILE_TYPE
|
||||
from string import Template
|
||||
from loguru import logger
|
||||
from common_utils.files_handle import get_files
|
||||
|
||||
|
||||
def get_yaml_data(file_path):
|
||||
"""
|
||||
从yaml/yml文件中获取用例数据
|
||||
:param file_path: yaml/yml文件绝对路径
|
||||
"""
|
||||
if os.path.isfile(file_path):
|
||||
# 读取yaml/yml文件中的用例数据,存储到data中
|
||||
return YamlHandle(file_path).read_yaml
|
||||
|
||||
|
||||
def get_excel_data(file_path):
|
||||
"""
|
||||
从xlsx/xls文件中获取用例数据
|
||||
:param file_path: xlsx/xls文件绝对路径
|
||||
"""
|
||||
if os.path.isfile(file_path):
|
||||
# 读取xlsx/xls文件中的用例数据,存储到data中
|
||||
return ExcelHandle(file_path).read()
|
||||
|
||||
|
||||
def gen_case_data_from_excel(files):
|
||||
cases = []
|
||||
for file in files:
|
||||
# 读取excel文件中的用例数据,存储到data中
|
||||
data = get_excel_data(file)
|
||||
for _data in data:
|
||||
# 将excel读取到的用例数据,适配allure格式
|
||||
excel_data = {
|
||||
'case_common': {'allure_epic': 'GitLink接口', 'allure_feature': _data["sheet_name"],
|
||||
'allure_story': _data["sheet_name"]},
|
||||
'case_info': _data["data"]
|
||||
}
|
||||
# 调用gen_case方法生成测试用例, 例如:test_demo.py
|
||||
gen_case_file(case_file_path=file, case_template_path=CASE_TEMPLATE_DIR, case_data=excel_data,
|
||||
target_case_path=AUTO_CASE_DIR)
|
||||
# 将获取到的用例数据统一保存到cases中
|
||||
cases.extend([excel_data])
|
||||
logger.debug(f"从{file}中读取到的用例数据是:{excel_data}")
|
||||
return cases
|
||||
|
||||
|
||||
def gen_case_data_from_yaml(files):
|
||||
cases = []
|
||||
for file in files:
|
||||
# 从yaml/yml中读取用例数据
|
||||
yaml_data = get_yaml_data(file)
|
||||
# 调用gen_case方法生成测试用例, 例如:test_demo.py
|
||||
gen_case_file(case_file_path=file, case_template_path=CASE_TEMPLATE_DIR, case_data=yaml_data,
|
||||
target_case_path=AUTO_CASE_DIR)
|
||||
# 将获取到的用例数据统一保存到cases中
|
||||
cases.extend([yaml_data])
|
||||
logger.debug(f"从{file}中读取到的用例数据是:{yaml_data}")
|
||||
return cases
|
||||
|
||||
|
||||
def get_case_data():
|
||||
"""
|
||||
根据配置文件,从指定类型文件中读取用例数据,并调用生成用例文件方法,生成用例文件
|
||||
"""
|
||||
cases = []
|
||||
# 判断配置文件里面CASE_DATA_TYPE,判断用例数据是从excel还是yaml文件中读取
|
||||
# 从excel中读取用例数据
|
||||
if CASE_FILE_TYPE == CaseFileType.EXCEL.value:
|
||||
# 在用例数据"DATA_DIR"目录中寻找后缀是xlsx, xls的文件
|
||||
files = get_files(target=DATA_DIR, start="test_", end=".xlsx") \
|
||||
+ get_files(target=DATA_DIR, start="test_", end=".xls")
|
||||
cases = gen_case_data_from_excel(files)
|
||||
return cases
|
||||
# 从yaml中读取用例数据
|
||||
elif CASE_FILE_TYPE == CaseFileType.YAML.value:
|
||||
# 在用例数据"DATA_DIR"目录中寻找后缀是yaml, yml的文件
|
||||
files = get_files(target=DATA_DIR, start="test_", end=".yaml") \
|
||||
+ get_files(target=DATA_DIR, start="test_", end=".yml")
|
||||
cases = gen_case_data_from_yaml(files)
|
||||
return cases
|
||||
else:
|
||||
# 在用例数据"DATA_DIR"目录中寻找后缀是xlsx,xls, yaml, yml的文件
|
||||
excel_files = get_files(target=DATA_DIR, start="test_", end=".xlsx") \
|
||||
+ get_files(target=DATA_DIR, start="test_", end=".xls")
|
||||
yaml_files = get_files(target=DATA_DIR, start="test_", end=".yaml") \
|
||||
+ get_files(target=DATA_DIR, start="test_", end=".yml")
|
||||
excel_cases = gen_case_data_from_excel(excel_files)
|
||||
cases.extend([excel_cases])
|
||||
yaml_cases = gen_case_data_from_yaml(yaml_files)
|
||||
cases.extend([yaml_cases])
|
||||
|
||||
return cases
|
||||
|
||||
|
||||
def gen_case_file(case_file_path, case_template_path, case_data, target_case_path):
|
||||
"""
|
||||
根据测试用例文件(yaml/yml/xlsx/xls),以及事先定义的测试用例模板,实际用例数据,生成测试用例方法(.py)
|
||||
:param case_file_path: 测试用例文件(yaml/yml/xlsx/xls)的绝对路径
|
||||
:param case_template_path: 测试用例模板的绝对路径
|
||||
:param case_data: 实际用例数据
|
||||
:param target_case_path: 测试用例方法(.py)的绝对路径
|
||||
"""
|
||||
# 如果自动生成用例的目录不存在则自动创建一个
|
||||
if not os.path.exists(AUTO_CASE_DIR):
|
||||
os.makedirs(AUTO_CASE_DIR)
|
||||
"""
|
||||
string.Template是将一个string设置为模板,通过替换变量的方法,最终得到想要的string。
|
||||
"""
|
||||
filename = os.path.basename(case_file_path)
|
||||
# 将用例数据的名称作为测试用例文件名称
|
||||
func_name = os.path.splitext(filename)[0]
|
||||
# 测试用例test_demo.py的类名是TestDemo
|
||||
class_name = func_name.split("_")[0].title() + func_name.split("_")[1].title()
|
||||
# 定义生成的测试用例的模板
|
||||
with open(file=case_template_path, mode="r", encoding="utf-8") as f:
|
||||
case_template = f.read()
|
||||
# 根据模板,生成测试用例方法
|
||||
my_case = Template(case_template).safe_substitute({"case_data": case_data,
|
||||
"func_title": func_name,
|
||||
"class_title": class_name})
|
||||
# 将测试用例方法写入py文件中
|
||||
with open(os.path.join(target_case_path, func_name + '.py'), "w", encoding="utf-8") as fp:
|
||||
fp.write(my_case)
|
||||
@@ -6,10 +6,10 @@
|
||||
# @Desc: 从测试报告中获取测试结果
|
||||
|
||||
import os
|
||||
from common_utils.bs4_handle import SoupAPI
|
||||
import json
|
||||
from common_utils.time_handle import timestamp_strftime
|
||||
from loguru import logger
|
||||
import json
|
||||
from common_utils.bs4_handle import SoupAPI
|
||||
from common_utils.time_handle import timestamp_strftime
|
||||
|
||||
|
||||
def get_test_results_from_pytest_html_report(html_report_path):
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
# @Software: PyCharm
|
||||
# @Desc: 处理request请求前后的用例数据
|
||||
import json
|
||||
import os.path
|
||||
from common_utils.files_handle import get_file_field
|
||||
from case_utils.data_handle import eval_data_process, data_handle
|
||||
from config.global_vars import GLOBAL_VARS
|
||||
import os
|
||||
from requests import Response
|
||||
from loguru import logger
|
||||
from common_utils.files_handle import get_file_field
|
||||
from common_utils.base_request import BaseRequest
|
||||
from case_utils.data_handle import eval_data_process, data_handle
|
||||
from case_utils.data_handle import json_extractor, re_extract
|
||||
from case_utils.allure_handle import allure_step
|
||||
from common_utils.base_request import BaseRequest
|
||||
from config.global_vars import GLOBAL_VARS
|
||||
from config.path_config import FILES_DIR
|
||||
|
||||
|
||||
@@ -76,10 +76,9 @@ class RequestPreDataHandle:
|
||||
用例数据中获取到的url(一般是不带host的,个别特殊的带有host,则不进行处理)
|
||||
"""
|
||||
# 检测url中是否存在需要替换的参数,如果存在则进行替换
|
||||
data_handle(obj=self.request_data.get("url", None), source=GLOBAL_VARS)
|
||||
url = data_handle(obj=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"):
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
# @Desc: 根据配置文件,发送指定通知
|
||||
|
||||
from loguru import logger
|
||||
from common_utils.yagmail_handle import YagEmailServe
|
||||
from config.models import NotificationType
|
||||
from config.settings import SEND_RESULT_TYPE, email, ding_talk, wechat, email_subject, email_content, ding_talk_title, \
|
||||
ding_talk_content, wechat_content
|
||||
from common_utils.dingding_handle import DingTalkBot
|
||||
from common_utils.wechat_handle import WechatBot
|
||||
from case_utils.data_handle import data_handle
|
||||
from case_utils.get_results_handle import get_test_results_from_pytest_html_report, \
|
||||
get_test_results_from_from_allure_report
|
||||
from common_utils.dingding_handle import DingTalkBot
|
||||
from common_utils.wechat_handle import WechatBot
|
||||
from common_utils.yagmail_handle import YagEmailServe
|
||||
|
||||
|
||||
def send_email(user, pwd, host, subject, content, to, attachments):
|
||||
@@ -126,7 +126,7 @@ def send_result(report_path, report_type="allure", attachment_path=None):
|
||||
notification = notification_mappings[SEND_RESULT_TYPE]
|
||||
# 获取消息内容并替换
|
||||
notification['sender_args']['content'] = data_handle(notification['sender_args']['content'],
|
||||
source=results)
|
||||
source=results)
|
||||
# 获取消息发送函数
|
||||
sender = notification['sender']
|
||||
# 获取对应消息发送函数的参数
|
||||
@@ -139,7 +139,7 @@ def send_result(report_path, report_type="allure", attachment_path=None):
|
||||
for notification in notification_mappings.values():
|
||||
# 获取消息内容并替换
|
||||
notification['sender_args']['content'] = data_handle(notification['sender_args']['content'],
|
||||
source=results)
|
||||
source=results)
|
||||
# 获取消息发送函数
|
||||
sender = notification['sender']
|
||||
# 获取对应消息发送函数的参数
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# @Time : 2023/6/22 14:11
|
||||
# @Author : chenyinhua
|
||||
# @File : base_request.py
|
||||
# @Software: PyCharm
|
||||
# @Desc: 封装的requests模块
|
||||
|
||||
import time
|
||||
from typing import Dict, Union
|
||||
import requests
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# @Author : chenyinhua
|
||||
# @File : http_server.py
|
||||
# @Software: PyCharm
|
||||
# @Desc:
|
||||
# @Desc: 封装的HTTP服务
|
||||
|
||||
import http.server
|
||||
import socketserver
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
# @Time : ${now}
|
||||
|
||||
import pytest
|
||||
from case_utils.assert_handle import assert_response, assert_sql
|
||||
from loguru import logger
|
||||
from case_utils.request_data_handle import RequestPreDataHandle, RequestHandle, after_request_extract
|
||||
from pytest_html import extras # 往pytest-html报告中填写额外的内容
|
||||
from case_utils.allure_handle import allure_title
|
||||
import allure
|
||||
from case_utils.assert_handle import assert_response, assert_sql
|
||||
from case_utils.request_data_handle import RequestPreDataHandle, RequestHandle, after_request_extract
|
||||
from case_utils.allure_handle import allure_title
|
||||
from config.settings import db_info
|
||||
from config.global_vars import GLOBAL_VARS
|
||||
from pytest_html import extras # 往pytest-html报告中填写额外的内容
|
||||
|
||||
# 用例数据
|
||||
cases = ${case_data}
|
||||
@@ -20,7 +20,6 @@ cases = ${case_data}
|
||||
class ${class_title}Auto:
|
||||
|
||||
@allure.story("${allure_story}")
|
||||
@pytest.mark.${func_title}
|
||||
@pytest.mark.auto
|
||||
@pytest.mark.parametrize("case", cases, ids=["{}".format(case["title"]) for case in cases])
|
||||
def ${func_title}_auto(self, case, extra):
|
||||
|
||||
@@ -17,6 +17,7 @@ ENV_VARS = {
|
||||
"test": {
|
||||
# 示例测试环境及示例测试账号
|
||||
"host": "https://testforgeplus.trustie.net/",
|
||||
"glcc_host": "https://testglcc.trustie.net",
|
||||
"login": "auotest",
|
||||
"password": "12345678",
|
||||
"nickname": "AutoTest",
|
||||
@@ -27,6 +28,7 @@ ENV_VARS = {
|
||||
},
|
||||
"live": {
|
||||
"host": "https://www.gitlink.org.cn",
|
||||
"glcc_host": "https://glcc.gitlink.org.cn",
|
||||
"login": "******",
|
||||
"password": "******",
|
||||
"nickname": "******",
|
||||
|
||||
40
data/gitlink/glcc/test_get_apply_information.yml
Normal file
40
data/gitlink/glcc/test_get_apply_information.yml
Normal file
@@ -0,0 +1,40 @@
|
||||
case_common:
|
||||
allure_epic: GitLink接口(自动生成用例)
|
||||
allure_feature: 开源夏令营模块
|
||||
allure_story: 获取项目列表接口
|
||||
|
||||
case_glcc_demo_01:
|
||||
feature: GLCC
|
||||
title: 获取已报名成功的项目数据
|
||||
run: True
|
||||
url: ${glcc_host}/api/applyInformation/list?curPage=1&pageSize=10000&round=2
|
||||
method: GET
|
||||
headers: {"Content-Type": "application/json; charset=utf-8;"}
|
||||
cookies:
|
||||
request_type: json
|
||||
payload:
|
||||
files:
|
||||
extract:
|
||||
assert_response:
|
||||
eq:
|
||||
http_code: 200
|
||||
$.message: success
|
||||
assert_sql:
|
||||
|
||||
case_glcc_demo_02:
|
||||
feature: GLCC
|
||||
title: 获取已报名成功的课题数据
|
||||
run: True
|
||||
url: https://glcc.gitlink.org.cn/api/applyInformation/taskList?curPage=1&pageSize=20&userId=&round=2
|
||||
method: GET
|
||||
headers: {"Content-Type": "application/json; charset=utf-8;"}
|
||||
cookies:
|
||||
request_type: json
|
||||
payload:
|
||||
files:
|
||||
extract:
|
||||
assert_response:
|
||||
eq:
|
||||
http_code: 200
|
||||
$.message: success
|
||||
assert_sql:
|
||||
10
run.py
10
run.py
@@ -18,17 +18,17 @@
|
||||
import os
|
||||
import shutil
|
||||
import pytest
|
||||
from config.path_config import REPORT_DIR, LOG_DIR, AUTO_CASE_DIR, CONF_DIR, LIB_DIR, ALLURE_RESULTS_DIR, \
|
||||
ALLURE_HTML_DIR
|
||||
from case_utils.case_fun_handle import generate_cases
|
||||
from loguru import logger
|
||||
import click
|
||||
from config.settings import LOG_LEVEL
|
||||
from config.global_vars import GLOBAL_VARS, ENV_VARS
|
||||
from datetime import datetime
|
||||
from case_utils.case_fun_handle import generate_cases
|
||||
from case_utils.platform_handle import PlatformHandle
|
||||
from case_utils.send_result_handle import send_result
|
||||
from case_utils.allure_handle import AllureReportBeautiful
|
||||
from config.path_config import REPORT_DIR, LOG_DIR, AUTO_CASE_DIR, CONF_DIR, LIB_DIR, ALLURE_RESULTS_DIR, \
|
||||
ALLURE_HTML_DIR
|
||||
from config.settings import LOG_LEVEL
|
||||
from config.global_vars import GLOBAL_VARS, ENV_VARS
|
||||
from common_utils.files_handle import zip_file, copy_file
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user