Skip to content

企业微信接口自动化测试实战

接口自动化测试

课程目标

  • 掌握接口自动化测试用例设计方法。
  • 掌握接口自动化测试中的各种格式的请求构造与响应断言技巧。
  • 掌握接口自动化测试中复杂断言方法。
  • L1
  • L2
  • L3
  • L4
  • L5

知识点总览

点击查看:接口自动化测试知识点梳理.xmind

需求说明

  • 企业微信
    • 企业微信是腾讯微信团队打造的企业通讯与办公工具。
    • 具有与微信一致的沟通体验,丰富的 OA 应用,和连接微信生态的能力。
    • 可帮助企业连接内部、连接生态伙伴、连接消费者。专业协作、安全管理、人即服务。
  • 完成企业微信部门管理接口自动化测试。
  • 环境准备
    1. 企业微信注册。
    2. 企业微信白名单配置步骤:https://ceshiren.com/t/topic/22768

实战思路

uml diagram

需求分析

企业微信 API 文档

请求方式: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 设计模式:
    • 封装。
    • 分层。
    • 把实现和测试用例以及断言进行拆分。

uml diagram

框架搭建
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

总结

  1. 接口自动化测试方案。
  2. 接口测试框架封装。