Python接口自动化

前言:

采用当今主流的语言加框架加测试报告进行接口测试,其中不足,请大家多多指出并协助更改。
这里非常感谢一位老哥:https://gitee.com/zy7y 感谢老哥多次指教

墙裂推荐语雀版:https://www.yuque.com/docs/share/dff93b31-cce0-4a7a-8d06-1540e659c32f?# 《Python-接口自动化(Request+pytest+allure)》

功能:

  1. get/post请求(上传文件),支持restful接口规范
  2. 压缩测试报告
  3. 生成allure漂亮的测试报告
  4. 发送邮件(后续会集成jenkins)
  5. 数据依赖

运行机制

  1. 通过读取配置文件,获取到host地址、提取token的jsonpath表达式,提取实际响应结果用来与预期结果对比的jsonpath表达式
  2. 读取excel用例文件数据,组成一个符合pytest参数化的用例数据,根据每列数据进行数据处理(token操作、数据依赖)
  3. token的写需要使用一个正常的登陆接口,并且接口中要返回token数据,才能提取;token的读需要请求携带有token的header,token无数据将不携带token
  4. 数据依赖处理,从excel中读取出来的格式{"用例编号":["jsonpath表达式1":"jsonpath表达式2"]},通过用例编号来获取对应的case的实际响应结果,通过jsonpath表达式提取对应的依赖参数字段,以及对应的值,最终会返回一个存储接口需要依赖数据的字典{"userid":500,"username":"ranyong"},在发送请求时与请求数据进行合并,组成一个新的data放在请求中
  5. 每次请求完之后将回写实际的响应结果到excel中
  6. 根据配置文件中配置的jsonpath表达式提取实际响应内容与excel中预期结果的数据对比
  7. 生成测试报告
  8. 压缩测试报告文件夹
  9. 发送邮件

环境依赖

名称 版本 作用
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

初始化安装

  1. 安装最新的 Pycharm 社区版

  2. 安装Python ,版本3.7+

  3. 安装allure2 ,点击链接内的Links---Download,解压到任意目录,并配置好环境变量

  4. 安装git ,完成后鼠标右键打开git bash,输入:

  5. 找一个目录,打开git bash,输入: git clone [https://gitee.com/ran_yong/api-auto.git](https://gitee.com/ran_yong/auto_uiautomator2.git)

  6. 打开Pycharm,打开上一步拉取下来的apiAutoTest文件夹,导入工程,点击settings---Project---Project Interpretor---add...---New environment---Location中在当前工程名后确认是否有/venv,没有的话手动输入,基本编译器选择python3的安装路径,确认即可

  7. 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步即可

  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': '华语'}
posted @ 2021-06-28 23:54  Daydayup,ran  阅读(295)  评论(0编辑  收藏  举报