企业微信接口自动化测试实战
接口自动化测试
课程目标
- 掌握接口自动化测试用例设计方法。
- 掌握接口自动化测试中的各种格式的请求构造与响应断言技巧。
- 掌握接口自动化测试中复杂断言方法。
- L1
- L2
- L3
- L4
- L5
知识点总览
点击查看:接口自动化测试知识点梳理.xmind
需求说明
- 企业微信
- 企业微信是腾讯微信团队打造的企业通讯与办公工具。
- 具有与微信一致的沟通体验,丰富的 OA 应用,和连接微信生态的能力。
- 可帮助企业连接内部、连接生态伙伴、连接消费者。专业协作、安全管理、人即服务。
- 完成企业微信部门管理接口自动化测试。
- 环境准备
- 企业微信注册。
- 企业微信白名单配置步骤:https://ceshiren.com/t/topic/22768
实战思路
需求分析
请求方式:GET/POST(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
请求包体:
...
参数说明:
...
权限说明:
...
返回结果:
...
参数说明:
...
接口测试用例
接口测试方案设计
接口测试方案实现
接口请求发送
- 使用requests发送请求。
接口鉴权处理
- token 处理。
接口的断言处理
用例独立性
- 用例和用例之间没有耦合关系。
# add 无需考虑在get之前执行或之后执行。
def test_add_department(self):
...
def test_get_department(self):
...
用例执行过程
- 添加 mark 标签以区分用例适用的不同的环境。
# p1级别用例
@pytest.mark.P1
# 冒烟测试用例
@pytest.mark.smoke
def test_get_department(self):
print("=======123")
assert False
用例的结果报告
- 注意:这些关键字的设定只要内部达成一致,设计合理即可。
allure 关键字 | 对应层级 |
---|---|
step | 调用接口,一个step一个接口 |
title | 对应测试用例,一个title一条用例 |
@allure.title("添加部门测试")
def test_add_department(self):
with allure.step("添加部门"):
print("添加部门")
with allure.step("获取子部门ID列表"):
print("获取子部门ID列表")
测试数据管理
- 在测试用例结束之后清理掉对应的测试数据。建议使用软删除,调用接口的方式。
@allure.title("添加xxx")
def test_add_department(self):
with allure.step("添加操作"):
print("添加操作")
with allure.step("获取操作"):
print("获取操作")
with allure.step("删除操作"):
print("删除操作")
测试环境管理
- 用例设计需要能够支持环境切换。
# 从环境变量读取当前环境
default = os.getenv("env", default="test")
# 读取对应的环境配置文件
data = yaml.safe_load(open(f"./config/{default}.yaml"))
# mac设置环境变量
export env=dev
# windows 设置环境变量
set env=dev
接口测试框架封装
项目结构
├── apis
│ ├── __init__.py
│ ├── base_api.py
│ ├── department.py
│ └── wework.py
├── config
│ ├── __init__.py
│ └── config.yaml
├── tests
│ ├── __init__.py
│ ├── test_departments.py
│ └── test_department_flow.py
└── utils
├── __init__.py
├── log_utils.py
└── utils.py
接口测试框架封装设计
- ApiObject 设计模式:
- 封装。
- 分层。
- 把实现和测试用例以及断言进行拆分。
框架搭建
token 获取
企业微信特有逻辑,完成 access_token 的获取
import requests
class Wework:
def __init__(self):
self.base_url = "https://qyapi.weixin.qq.com"
self.token = self.get_access_token()
def get_access_token(self):
'''
获取 access_token
:return:
'''
# 定义凭证
corpid = "xxx"
corpsecret = "xxx"
url = f"{self.base_url}/cgi-bin/gettoken"
# 定义请求参数
params = {
"corpid": corpid,
"corpsecret": corpsecret
}
# 发送 GET 请求
r = requests.request("GET", url, params=params)
# 打印响应体
print(r.text)
# 获取 access_token
token = r.json().get("access_token")
return token
业务接口描述
接口信息描述:只关注业务,不需要做断言。每个方法返回接口响应体。
import requests
# 部门需要继承 Wework,这样就可以直接获取 Wework 中获取到的 access_token
class Department(Wework):
def create(self, data):
'''
创建部门
:return:
'''
return r
def update(self, data):
'''
更新部门信息
:return:
'''
return r
def delete(self, depart_id):
'''
删除部门
:return:
'''
return r
def get(self):
'''
获取子部门 id
:return:
'''
return r
创建测试用例
from jsonpath import jsonpath
class TestDepartments:
def setup_class(self):
# 实例化部门类
self.department = Department()
# 准备测试数据
self.depart_id = 210
self.create_data = {
"name": "广州研发中心",
"name_en": "RDGZ",
"parentid": 1,
"order": 1,
"id": self.depart_id
}
self.update_name = "广州研发中心-update"
self.update_data = {
"id": self.depart_id,
"name": self.update_name
}
def test_department_flow(self):
'''
部门增删改查场景测试
'''
# 创建部门
r = self.department.create(self.create_data)
assert r.status_code == 200
assert r.json().get("errcode") == 0
# 查询是否创建成功
r = self.department.get()
depart_ids = jsonpath(r.json(), "$..id")
assert self.depart_id in depart_ids
# 更新部门信息
r = self.department.update(self.update_data)
assert r.status_code == 200
assert r.json().get("errcode") == 0
# 删除部门
r = self.department.delete(self.depart_id)
assert r.status_code == 200
assert r.json().get("errcode") == 0
# 查询是否删除成功
r = self.department.get()
depart_ids = jsonpath(r.json(), "$..id")
assert self.depart_id not in depart_ids
接口调用封装
把 requests 封装到 BaseApi 中,供框架中其他方法调用。
import requests
class BaseApi:
def send_api(self, req):
'''
对 requests 进行二次封装
:return: 接口响应
'''
logger.debug(f"请求数据为==========>{req}")
r = requests.request(**req)
logger.debug(f"响应数据为<=========={r.text}")
return r
接下来把接口信息封装到字典中,这样接口描述中不需要直接调用 requests。
class Wework(BaseApi):
def __init__(self):
self.base_url = "https://qyapi.weixin.qq.com"
self.token = self.get_access_token()
def get_access_token(self):
'''
获取 access_token
:return:
'''
# 定义凭证
corpid = "xxx"
corpsecret = "xxx"
url = f"{self.base_url}/cgi-bin/gettoken"
req = {
"method": "GET",
"url": url,
"params": {
"corpid": corpid,
"corpsecret": corpsecret
}
}
r = self.send_api(req)
# 打印响应体
print(r.text)
# 获取 access_token
token = r.json().get("access_token")
return token
总结
- 接口自动化测试方案。
- 接口测试框架封装。