接口自动化测试

霍格沃兹测试开发学社

ceshiren.com

目录

  • 学习价值
  • 直播前准备
  • 知识点梳理
  • 企业微信接口自动化测试实战演练
  • 总结

学习价值

直播前准备

专题课 阶段 形式 章节
接口自动化测试 L1 知识点 全部录播
接口自动化测试 L2 知识点 多层嵌套响应断言
接口自动化测试 L2 知识点 【实战】宠物商店接口自动化测试实战
接口自动化测试 L3 知识点 整体结构响应断言
接口自动化测试 L3 知识点 数据库操作与断言
接口自动化测试 L4 知识点 多套被测环境

知识点梳理

接口自动化测试场景

接口自动化测试在企业中的实践

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

  • 实战目标
  • 被测产品介绍
  • 需求说明
  • 实战思路
  • 实战演练

思考

  1. 写接口自动化测试用例时,你使用了 requests 库,那大概使用到了 requests 的哪里内容?
  2. 接口自动化实现思路?
  3. 其他接口都需要登录接口的信息,怎么去让这个登录的接口只在其他接口调用一次?
  4. 接口产生的垃圾数据如何清理?
  5. 接口响应值嵌套较深,获取不方便怎么办?
  6. 接口的返回字段特别多,结构特别复杂时,如何做断言?

实战目标

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

成果展示

├── apis
│   ├── __init__.py
│   ├── base_api.py
│   ├── department.py
│   └── wework.py
├── config
│   ├── __init__.py
│   ├── config.yaml
│   └── secrets.yaml
├── tests
│   ├── __init__.py
│   ├── schema.json
│   ├── test_departments.py
│   └── test_department_flow.py
└── utils
    ├── __init__.py
    ├── log_utils.py
    └── utils.py

被测产品介绍

  • 企业微信
    • 企业微信是腾讯微信团队打造的企业通讯与办公工具。
    • 具有与微信一致的沟通体验,丰富的 OA 应用,和连接微信生态的能力。
    • 可帮助企业连接内部、连接生态伙伴、连接消费者。专业协作、安全管理、人即服务。

需求说明

  • 完成企业微信部门管理接口自动化测试。
  • 环境准备
    1. 企业微信注册(有手机号即可)。
    2. 企业微信白名单配置:https://ceshiren.com/t/topic/22768

实战思路

相关知识点

形式 章节
知识点 接口自动化测试框架介绍
知识点 接口请求方法
知识点 接口请求参数
知识点 接口请求头
知识点 接口请求体-json
知识点 接口响应断言
知识点 json 响应体断言
知识点 【实战】宠物商店接口自动化测试实战
知识点 多层嵌套响应断言
知识点 【实战】宠物商店接口自动化测试实战
知识点 整体结构响应断言
知识点 数据库操作与断言
知识点 多套被测环境

接口文档分析

请求方式:GET/POST(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
请求包体:
...
参数说明:
...
权限说明:
...
返回结果:
...
参数说明:
...

接口自动化测试

  • 接口鉴权
  • 接口测试用例设计
  • 接口自动化测试脚本

接口鉴权

接口测试用例

接口自动化测试脚本

  • 单接口测试
  • 接口业务场景测试
class TestDepartments:
    def setup_class(self):
        # 定义凭证
        corpid = "xxx"
        corpsecret = "xxx"

        url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"

        # 定义param
        params = {
            "corpid": corpid,
            "corpsecret": corpsecret
        }

        # 发get请求
        r = requests.request(method="GET", url=url, params=params)
        # 获取 access_token 定义为实例变量
        self.token = r.json()["access_token"]


    def test_create_department(self):
        url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"
        data = {
            "name": "广州研发中心2",
            "name_en": "RDGZ2",
            "parentid": 1,
            "order": 1,
            "id": 3}
        params = {
            "access_token":self.token
        }
        r = requests.request(method="POST", url=url, params = params,json=data)
        assert r.json()["errcode"] == 0

    @pytest.mark.parametrize(
        "name, name_en, parentid, order, depart_id, expect",
        [
            ("技术部", "JISHU1", 1, 1, 2, 0),
            ("技术部1t6yujk9osjhynnj890lkmbg54321", "JISHU2", 1, 2, 3, 0),
            ("技术部23", "JISHU23", 1, 23, 1, 60123)
        ]
    )
    def test_create_department(self, name, name_en, parentid, order, depart_id, expect):
        url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"
        data = {
            "name": name,
            "name_en": name_en,
            "parentid": parentid,
            "order": order,
            "id": depart_id
        }
        params = {
            "access_token": self.token
        }
        r = requests.request(method="POST", url=url, params=params, json=data)
        print(r.json())
        assert r.json()["errcode"] == expect

    def test_create_department_exist(self):
        # 1. 准备已存在部门
        # 2. 查询部门创建成果
        # 3. 有存在部门的情况下,创建相同信息的部门
        # 4. 删除部门
        # 5. 查询部门删除成功
        # 6. 再次创建部门
        # 7. 查询部门创建成功

接口测试框架封装

  • ApiObject 设计模式:
    • 封装。
    • 分层。
    • 把实现和测试用例以及断言进行拆分。

课堂练习

将代码进行优化,要求:

  1. 日志打印。
  2. 接口和业务(用例)分离。
  3. 添加 token 的过程不要体现在接口中。

复杂断言优化

  • 多层嵌套响应断言
  • 整体结构响应断言
  • 数据库断言

多层嵌套响应断言

import requests
from jsonpath import jsonpath


def test_json_path():
    r = requests.get("https://ceshiren.com/categories.json")
    name_list = jsonpath(r.json(), '$.category_list.categories[0].name')
    assert name_list[0] == '提问区'
    name_list = jsonpath(r.json(), "$..name")
    assert '提问区' in name_list

整体结构响应断言

  • 结合录播:
    • 《整体结构响应断言》
# 整体结构响应断言
class SchemaUtils:
    @classmethod
    def generate_schema(cls, obj, file_path):
        '''
        生成 json schema 文件
        :param obj: 要生成 schema 的 python 对象
        '''
        builder = SchemaBuilder()
        # 把预期响应添加到 builder 中
        builder.add_object(obj)
        # 生成 jsonschema
        schema_content = builder.to_schema()
        print(schema_content)
        # 写入 json 文件
        with open(file_path, "w", encoding="utf-8") as f:
            json.dump(schema_content, f)

    @classmethod
    def schema_validate(cls, obj, schema):
        '''
        对比 python 对象与生成的 json schema 结构是否一致
        :param obj: json 格式对象
        :param schema: 生成的 json schema 结构
        :return: 传入的 json 格式对象符合 schema 格式则返回 True,反之返回 False
        '''
        try:
            validate(instance=obj, schema=schema)
            return True
        except Exception as e:
            print(f"schema 校验异常======>{e}")
            return False

数据库断言

  • 数据库断言:pymysql:
    • 使用场景:验证数据操作的实际结果是否正确。
# 数据库
def query_db(cls, sql, database_info):
    # 连接数据库
    conn = pymysql.Connect(**database_info)
    # 创建游标
    cursor = conn.cursor()
    # 执行 SQL 语句
    cursor.execute(sql)
    # 获取查询结果
    datas = cursor.fetchall()
    print("查询到的数据为:", datas)  # 获取多条数据
    # 关闭连接
    cursor.close()
    conn.close()
    return datas

多环境切换场景优化

  • 结合录播:
    • 《多套被测环境》

接口自动化测试常见问题(一)

  1. 写接口自动化测试用例时,你使用了 requests 库,那大概使用到了 requests 的哪里内容?
    • 知识点梳理。
  2. 接口自动化实现思路?
    • 练习思路。
  3. 其他接口都需要登录接口的信息,怎么去让这个登录的接口只在其他接口调用一次?
    • 获取 token 的之前添加判断,如果存在则不获取。

接口自动化测试常见问题(二)

  1. 接口产生的垃圾数据如何清理?
    • 方式一:专门准备一个自动化测试环境,测完直接做数据回滚
    • 方式二:每次创建完数据,都调用 delete 接口删除
    • 注意:尽量不要用数据库直接删除,容易引起 bug
  2. 接口响应值嵌套较深,获取不方便怎么办?
    • JsonPath 表达式提取。
  3. 接口的返回字段特别多,结构特别复杂时,如何做断言?
    • JsonSchema 做结构断言。

总结

  • 接口自动化知识点梳理。
  • 企业微信实战练习。
  • 接口自动化测试常见问题的梳理。

作业