接口断言模式之相等断言模式和包含断言模式

一.相等断言模式

示例代码

    def equal_assert(self, expected_results, actual_results, status_code=None):
        """
        相等断言模式
        :param expected_results: 预期结果,yaml文件validation值
        :param actual_results: 接口实际响应结果
        :return:
        """
        flag = 0
        if isinstance(actual_results, dict) and isinstance(expected_results, dict):
            # 找出实际结果与预期结果共同的key
            common_keys = list(expected_results.keys() & actual_results.keys())[0]
            # 根据相同的key去实际结果中获取,并重新生成一个实际结果的字典
            new_actual_results = {common_keys: actual_results[common_keys]}
            eq_assert = operator.eq(new_actual_results, expected_results)
            if eq_assert:
                logs.info(f"相等断言成功:接口实际结果:{new_actual_results},等于预期结果:" + str(expected_results))
                allure.attach(f"预期结果:{str(expected_results)}\n实际结果:{new_actual_results}", '相等断言结果:成功',
                              attachment_type=allure.attachment_type.TEXT)
            else:
                flag += 1
                logs.error(f"相等断言失败:接口实际结果{new_actual_results},不等于预期结果:" + str(expected_results))
                allure.attach(f"预期结果:{str(expected_results)}\n实际结果:{new_actual_results}", '相等断言结果:失败',
                              attachment_type=allure.attachment_type.TEXT)
        else:
            raise TypeError('相等断言--类型错误,预期结果和接口实际响应结果必须为字典类型!')
        return flag

方法说明

方法名称

def equal_assert(self, expected_results, actual_results, status_code=None)

功能描述

该方法用于实现 相等断言(Equal Assertion),即验证接口返回的实际结果中某个字段的值是否 完全等于预期值

通过对比两个字典对象(实际结果与预期结果)中的指定字段内容,判断其是否完全一致。


示例场景

  • 验证接口返回的 code 是否为 200
  • 验证响应中的 user.id 是否等于预期值
  • 验证嵌套结构中的某个字段是否完全匹配预期值

参数说明

参数名类型描述
expected_resultsdict预期结果,通常来自 YAML 文件中的 validation 字段,例如:{"code": 200}
actual_resultsdict接口实际返回的 JSON 响应体
statuc_codeint(可选)HTTP 状态码(当前未使用,且参数名存在拼写错误)

返回值说明

  • 返回一个整数类型 flag
    • 0 表示断言成功
    • 1 表示断言失败

执行逻辑详解

1. 初始化标志位
flag = 0

默认表示所有断言通过。


2. 类型校验
if isinstance(actual_results, dict) and isinstance(expected_results, dict):
  • 如果传入的 actual_results 和 expected_results 不是字典类型,则抛出异常:
raise TypeError('相等断言--类型错误,预期结果和接口实际响应结果必须为字典类型!')

3. 获取公共 key(要比较的字段)
common_keys = list(expected_results.keys() & actual_results.keys())[0]
  • 使用集合运算符 & 找出两个字典共有的 key。
  • 取第一个作为比较字段(⚠️ 当前仅支持单字段比较)。

4. 构造新的实际结果字典
new_actual_results = {common_keys: actual_results[common_keys]}
  • 从实际响应中提取对应字段的值,构造一个新的字典。

5. 使用 operator.eq 进行深度比较
eq_assert = operator.eq(new_actual_results, expected_results)
  • operator.eq() 是 Python 的深度比较函数,可以比较复杂数据结构(如嵌套字典、列表等)是否完全相同。
  • 相比 == 更加严格和可靠。

6. 成功/失败处理
成功时:
logs.info("相等断言成功...")
allure.attach(...)
  • 记录日志并附加到 Allure 报告中。
失败时:
flag += 1
logs.error("相等断言失败...")
allure.attach(...)
  • 标记失败,记录错误日志,并将断言信息附加到报告中

二.包含断言模式

代码示例

def contains_assert(self, value, response, status_code):
        """
        字符串包含断言模式,断言预期结果的字符串是否包含在接口的响应信息中
        :param value: 预期结果,yaml文件的预期结果值
        :param response: 接口实际响应结果
        :param status_code: 响应状态码
        :return: 返回结果的状态标识
        """
        # 断言状态标识,0成功,其他失败
        flag = 0
        for assert_key, assert_value in value.items():
            if assert_key == "status_code":
                if assert_value != status_code:
                    flag += 1
                    allure.attach(f"预期结果:{assert_value}\n实际结果:{status_code}", '响应代码断言结果:失败',
                                  attachment_type=allure.attachment_type.TEXT)
                    logs.error("contains断言失败:接口返回码【%s】不等于【%s】" % (status_code, assert_value))
            else:
                resp_list = jsonpath.jsonpath(response, "$..%s" % assert_key)
                if isinstance(resp_list[0], str):
                    resp_list = ''.join(resp_list)
                if resp_list:
                    assert_value = None if assert_value.upper() == 'NONE' else assert_value
                    if assert_value in resp_list:
                        logs.info("字符串包含断言成功:预期结果【%s】,实际结果【%s】" % (assert_value, resp_list))
                    else:
                        flag = flag + 1
                        allure.attach(f"预期结果:{assert_value}\n实际结果:{resp_list}", '响应文本断言结果:失败',
                                      attachment_type=allure.attachment_type.TEXT)
                        logs.error("响应文本断言失败:预期结果为【%s】,实际结果为【%s】" % (assert_value, resp_list))
        return flag

方法说明

方法名称

def contains_assert(self, value, response, status_code)

该方法用于实现 字符串包含断言(Contains Assertion),即验证接口响应中是否 包含预期的关键字段和值。支持对状态码和 JSON 响应内容进行断言。


示例场景

  • 验证返回的 msg 是否包含 "登录成功"
  • 验证 HTTP 状态码是否为 200
  • 验证响应中的某个字段是否包含指定值

参数说明

参数名类型描述
valuedict从 YAML 文件中读取的断言规则,例如 { "code": 200, "msg": "登录成功" }
responsedict接口实际返回的 JSON 响应体
status_codeint接口返回的 HTTP 状态码

返回值说明

  • 返回一个整数类型 flag
    • 0 表示所有断言通过
    • 大于 0 表示有断言失败,数值表示失败次数

执行逻辑详解

1. 初始化标志位
flag = 0

默认表示所有断言通过。


2. 遍历断言字典
for assert_key, assert_value in value.items():

遍历传入的 value 字典,获取每个断言字段及其预期值。


3. 判断是否为状态码断言
if assert_key == "status_code":
    if assert_value != status_code:
        flag += 1
        allure.attach(...)  # 添加失败信息到 Allure 报告
        logs.error(...)     # 记录错误日志
  • 如果是 "status_code",则比较预期值与实际状态码。
  • 不相等时标记失败,并记录日志和报告信息。

4. 否则进行响应内容断言(JSONPath 提取 + 包含判断)
resp_list = jsonpath.jsonpath(response, "$..%s" % assert_key)

使用 jsonpath.jsonpath() 从响应数据中提取所有名为 assert_key 的字段值。

response = {"code": 200, "data": {"msg": "登录成功"}}
assert_key = "msg"
resp_list = jsonpath.jsonpath(response, "$..msg") → ["登录成功"]

对结果做类型处理
if isinstance(resp_list[0], str):
    resp_list = ''.join(resp_list)
  • 如果提取到的是字符串列表,合并成单个字符串方便后续判断。

判断是否为空值(如 NONE)
assert_value = None if assert_value.upper() == 'NONE' else assert_value
  • 支持将字符串 'NONE' 转换为 Python 的 None,便于后续判断空值。

实际断言逻辑
if assert_value in resp_list:
    logs.info("成功")
else:
    flag += 1
    allure.attach(...)
    logs.error("失败")
  • 如果预期值存在于响应字段中,则断言成功。
  • 否则标记失败,记录日志并附加报告信息。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值