Python接口自动化
前言:
采用当今主流的语言加框架加测试报告进行接口测试,其中不足,请大家多多指出并协助更改。
这里非常感谢一位老哥:https://gitee.com/zy7y 感谢老哥多次指教
墙裂推荐语雀版:https://www.yuque.com/docs/share/dff93b31-cce0-4a7a-8d06-1540e659c32f?# 《Python-接口自动化(Request+pytest+allure)》
功能:
- get/post请求(上传文件),支持restful接口规范
- 压缩测试报告
- 生成allure漂亮的测试报告
- 发送邮件(后续会集成jenkins)
- 数据依赖
运行机制
- 通过读取配置文件,获取到host地址、提取token的jsonpath表达式,提取实际响应结果用来与预期结果对比的jsonpath表达式
- 读取excel用例文件数据,组成一个符合pytest参数化的用例数据,根据每列数据进行数据处理(token操作、数据依赖)
- token的写需要使用一个正常的登陆接口,并且接口中要返回token数据,才能提取;token的读需要请求携带有token的header,token无数据将不携带token
- 数据依赖处理,从excel中读取出来的格式{"用例编号":["jsonpath表达式1":"jsonpath表达式2"]},通过用例编号来获取对应的case的实际响应结果,通过jsonpath表达式提取对应的依赖参数字段,以及对应的值,最终会返回一个存储接口需要依赖数据的字典{"userid":500,"username":"ranyong"},在发送请求时与请求数据进行合并,组成一个新的data放在请求中
每次请求完之后将回写实际的响应结果到excel中- 根据配置文件中配置的jsonpath表达式提取实际响应内容与excel中预期结果的数据对比
- 生成测试报告
- 压缩测试报告文件夹
- 发送邮件
环境依赖
名称 | 版本 | 作用 |
---|---|---|
python | 3.7.8+ | 写代码核心工具 |
pytest | 6.0.1 | 底层单元测试框架,用来实现参数化,自动执行用例 |
allure-pytest | 2.8.17 | allure与pytest的插件可以生成allure的测试报告 |
jsonpath | 0.82 | 用来进行响应断言操作 |
loguru | 0.54 | 记录日志 |
PyYAML | 5.3.1 | 读取yml/yaml格式的配置文件 |
Allure | 2.13.5 | 要生成allure测试报告必须要在本机安装allure并配置环境变量 |
xlrd | 1.2.0 | 用来读取excel中用例数据 |
yagmail | 0.11.224 | 测试完成后发送邮件 |
requests | 2.24.0 | 发送请求 |
目录结构
├─api
│ ├─__init__.py # 初始化
│ └─base_requests.py # 请求封装
├─config
│ └─config.yaml # 配置文件
├─data
│ └─test_data.xls # Excel用例文件
├─test
│ ├─conftest.py # 依赖对象初始化
│ └─test_api.py # 测试文件
├─log
│ └─run...x.log # 日志文件
├─report
│ ├─data
│ └─html # allure报告
├─tools # 工具包
│ ├─__init__.py # 常用方法封装
│ ├─data_process.py # 依赖数据处理
│ ├─db.py # 数据库连接对象
│ ├─hooks.py # 自定义扩展方法(可配合用例)文件
│ ├─read_file.py # 用例、配置项读取
│ └─send_email.py # 邮件发送、报告压缩
├─requirements.txt # 项目依赖库文件
└─run.py # 主启动文件(一键运行)
执行顺序
代码实现
首先了解下yaml文件的基础知识
Yaml文件初识:
以下为yaml文件的一个示例:
student:
name: chen
age: 18
sex: 男
class: 11
转换为json格式时:
{
"student": {
"name": "chen",
"age": 18,
"sex": "男",
"class": 11
}
}
以上可以看出,yaml的基本写法是比较简单的,注意的是,同一级的字段要对齐,冒号后面要带上空格。切记!切记!
yaml基础语法:
- 大小写敏感
- 使用缩进表示层级关系
- 缩进不能使用tab,只允许空格
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- '#'表示注释
详细了解请移步:https://www.runoob.com/w3cnote/yaml-intro.html
初始化安装
-
安装最新的 Pycharm 社区版
-
安装Python ,版本3.7+
-
安装allure2 ,点击链接内的Links---Download,解压到任意目录,并配置好环境变量
-
安装git ,完成后鼠标右键打开git bash,输入:
-
找一个目录,打开git bash,输入:
git clone [https://gitee.com/ran_yong/api-auto.git](https://gitee.com/ran_yong/auto_uiautomator2.git)
-
打开Pycharm,打开上一步拉取下来的apiAutoTest文件夹,导入工程,点击settings---Project---Project Interpretor---add...---New environment---Location中在当前工程名后确认是否有/venv,没有的话手动输入,基本编译器选择python3的安装路径,确认即可
-
Pycharm需要先配置pip的repositories,推荐https://pypi.tuna.tsinghua.edu.cn/simple/ ,Pycharm的Terminal中,输入:
pip3 install -r requirements.txt
(若下载超时:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt) 等待安装完成后,环境就配置完成了,后续执行测试只要执行下面的第8步即可 -
直接运行对应应用目录下的
run.py
即可
Excel用例展示
用例编号 | 用例标题 | Header自定义会被追加到基准header | 接口地址(/&....表示可变路径参数,实际值从响应字典读取) | 是否执行 | 请求方式 | 入参关键字 | 上传文件({文件接受参数对象: 上传文件的路径}) | 请求数据(&语法&,提取前面依赖数据字典中对应key的值) | 后置sql | 预期结果(实际:预期- 其中预期支持请求参数一样的提取语法) | 保存响应(建议在该用例的实际响应结果会被其他用例使用时,才保存) |
---|---|---|---|---|---|---|---|---|---|---|---|
case_001 | get请求实现登录 | login | 是 | get | params | 是 | |||||
case_002 | post请求实现登录 | login | 是 | post | data | select * from user where id=&$.case_002.data.id&; | {"$.meta":{ "msg": "登录成功", "status": 200 }} | 是 | |||
case_003 | get请求查询用户数据列表 | users | 是 | get | params | {"$.meta":{"msg": "获取管理员列表成功", "status": 200}} | 是 | ||||
case_004 | get请求查询用户数据列表 | users | 是 | get | data | {"$.meta":{"msg": "获取管理员列表成功", "status": 200}} | 是 | ||||
case_005 | 添加用户正常接口数据 | users | 是 | post | data | {"$.meta":{"msg":"创建成功","status":201}} | 是 | ||||
case_006 | 修改用户状态接口 | users/&$.case_005.data.id&/state/&$.case_005.data.careate_time& | 是 | put | data | {"$.meta":{"msg": "设置状态成功", "status": 200}} | 是 | ||||
case_007 | 修改用户状态为2 | users/&$.case_005.data.id&/state/2 | 是 | put | data | {"$.meta":{"msg": "设置状态成功", "status": 200}} | 是 | ||||
case_008 | win10-本地测试上传单文件接口 | upload_file/ | 否 | post | data | {"$.meta":{"msg": "ok"}} | 是 | ||||
case_009 | win10-本地测试上传多文件接口 | upload_files/ | 否 | post | data | {"$.meta":{"msg": "ok"}} | 是 | ||||
case_001 | 百度收录查询 | @md5_encode2()@ | api-baidu_entry | 是 | get | params | 是 |
todo:差一个图
查看测试报告
运行run.py完成测试后会自动处理报告并使用默认浏览器打开报告,若关闭后想再次打开,请在pycharm中找到对应报告的目录下的index.html,右击--Open in Browser
base64编码和解码
题外话:将数据加密成密文然后在传出去
此加密不能用字典类型的
需要将类型转换为字节
# 编码数据
import base64
import json
json_data = {
"tag": "movie",
"type": "华语"
}
str_json = json.dumps(json_data)
print(type(str_json), str_json)
b_str_json = str_json.encode()
print(type(b_str_json))
# 数据加密
print(base64.b64encode(b_str_json))
# 解码数据
import base64
import json
json_data = {
"tag": "movie",
"type": "华语"
}
encode_data = b'eyJ0YWciOiAibW92aWUiLCAidHlwZSI6ICJcdTUzNGVcdThiZWQifQ=='
print(base64.b64decode(encode_data))
b_str_json = base64.b64decode(encode_data) # b'{"tag": "movie", "type": "\\u534e\\u8bed"}'
# 字节类型转换为字符串
str_json = b_str_json.decode()
print(type(str_json), str_json) # <class 'str'=""> {"tag": "movie", "type": "\u534e\u8bed"}
print(json.loads(str_json)) # {'tag': 'movie', 'type': '华语'}