5:原生 assert 断言

上篇讲解 Pytest 类 & 方法级前后置 setup_class/setup_method,本篇聚焦测试核心:断言。自动化用例靠断言判定执行结果,Pytest 摒弃 unittest 繁琐断言方法,直接使用 Python 原生 assert,简洁高效,是接口、UI 自动化高频用法。

一、什么是断言?Pytest 选用原生 assert 的优势

断言用来校验程序实际结果与预期结果是否一致:条件为 True,用例通过;条件为 False,抛出 AssertionError,用例失败终止执行。

对比 unittest,Pytest assert 两大优点

  1. **语法极简:**不用记忆self.assertEqual、self.assertIn、self.assertTrue等一堆方法,直接用原生运算符==、>、in、is,降低学习成本。
  2. 报错详情自动解析 :Pytest 底层重写 assert,失败自动打印实际值、期望值、变量来源、数据差异,不用手动拼接日志排查问题。

unittest 冗余示例:

python 复制代码
import unittest
class TestDemo(unittest.TestCase):
    def test_01(self):
        res = 2+3
        self.assertEqual(res,6,"结果错误")

Pytest 简洁写法:

python 复制代码
def test_01():
    res = 2+3
    assert res ==6, f"预期6,实际{res}"

二、assert 基础语法

python 复制代码
assert 布尔表达式, "自定义失败提示文案(可选)"
  • 布尔表达式:满足条件 = True → 用例放行;不满足 = False → 断言失败
  • 自定义提示:失败时优先展示自定义信息,便于快速定位业务问题,自动化项目必加

基础示例:

python 复制代码
# test_assert_base.py
def test_assert_demo():
    expect = 200
    actual = 200
    # 成功,无报错
    assert actual == expect
    # 失败,抛出异常+自定义提示
    actual2 = 500
    assert actual2 == expect, f"接口状态码异常:预期{expect},实际{actual2}"

执行:pytest -vs test_assert_base.py

三、自动化高频场景:全类型断言实战(接口测试最常用)

1. 数值断言(状态码、数字结果)

==、!=、>、>=、<、<=,多用于接口响应码、返回数值校验

python 复制代码
def test_num_assert():
    code = 200
    # 等于
    assert code == 200, "请求成功状态码必须200"
    # 大于
    assert code > 100
    # 不等于
    assert code != 500

2. 字符串断言(返回文本、错误信息)

in / not in、==,校验返回内容是否包含指定关键字

python 复制代码
def test_str_assert():
    res_text = "login success"
    assert "success" in res_text, "登录返回结果不含success"
    assert "fail" not in res_text

3. 列表 / 元组断言(批量返回数据)

长度、成员存在性校验

python 复制代码
def test_list_assert():
    data_list = [10,20,30]
    # 判断长度
    assert len(data_list) ==3, "返回数据条数错误"
    # 判断元素存在
    assert 20 in data_list

4. 字典断言(接口返回 JSON,接口自动化重中之重)

键存在、键值匹配,90% 接口用例都会用到

python 复制代码
def test_dict_assert():
    resp = {"code":200,"msg":"ok","data":{"uid":1001}}
    # 校验key是否存在
    assert "code" in resp
    # 校验value
    assert resp["code"] ==200
    # 嵌套字典取值断言
    assert resp["data"]["uid"] ==1001

5. 布尔值断言

python 复制代码
def test_bool_assert():
    flag = True
    assert flag is True

四、pytest.raises 异常断言:预判代码抛出指定异常

部分用例需要校验错误入参是否抛出预期异常,不用 try-except 捕获

使用**with pytest.raises(异常类型)**实现,异常匹配则用例通过,未抛异常则失败。

基础用法

python 复制代码
import pytest
def test_exception():
    # 预期传入非数字字符串,触发ValueError
    with pytest.raises(ValueError):
        int("abc123")

进阶:捕获异常信息

python 复制代码
def test_exception_msg():
    with pytest.raises(ValueError) as err_info:
        int("test")
    # 断言异常描述包含指定内容
    assert "invalid literal for int()" in str(err_info.value)

五、自定义报错信息规范(项目实战最佳实践)

不要只写assert xxx ==xx,"断言失败"模糊提示,规范格式: assert 条件, f"【业务场景】预期XX,实际XX"

python 复制代码
# 规范写法
resp_code = 404
expect_code =200
assert resp_code == expect_code, f"【用户登录接口】状态码异常:预期{expect_code},实际{resp_code}"

好处:流水线报错一眼定位接口与问题,节省排查时间。

六、Pytest 自动优化:复杂数据断言差异化报错

原生 Pytest 对长字符串、字典、列表会自动对比差异:

  1. 字符串不一致:高亮不同字符位置
  2. 字典不一致:标出 key 和 value 差异
  3. 列表不一致:提示第一个不匹配下标 示例报错:
python 复制代码
E       assert {'code': 200, 'msg': 'ok'} == {'code': 500, 'msg': 'fail'}
E         Differing items:
E         {'code': 200 != 500, 'msg': 'ok' != 'fail'}

七、开发踩坑注意事项

  1. 不要在 assert 表达式中写业务逻辑 :Python 使用python -O运行时会全局禁用所有 assert,表达式内代码不会执行,只做结果判断。
python 复制代码
# 错误:删除数据写在断言里,-O执行时代码失效
assert del_data() == True
# 正确:逻辑前置,只断言结果
res = del_data()
assert res == True
  1. 自定义提示要用 f-string 动态拼接实际值,固定文案无排查意义。

八、前后置 + 断言综合实战(整合上篇知识点)

类前置统一初始化请求、方法前置单用例准备数据,最后用断言校验结果,企业标准用例模板

python 复制代码
class TestLoginApi:
    def setup_class(self):
        print("【类前置】初始化请求头、全局url")
        self.headers = {"Content-Type":"application/json"}

    def setup_method(self):
        print("【方法前置】准备账号数据")
        self.account = {"user":"test01","pwd":"123456"}

    def test_login_success(self):
        # 模拟接口返回
        resp = {"code":200,"msg":"登录成功"}
        # 多层断言
        assert resp["code"] ==200, f"登录失败,状态码{resp['code']}"
        assert "成功" in resp["msg"]
相关推荐
覆东流11 小时前
7.Java数组
java·开发语言·后端
码行山野赴时序归途12 小时前
三道经典数组题:从暴力到最优的算法思维
c语言·开发语言·数据结构·算法·leetcode
lzhdim12 小时前
提高 SQL 语句执行速度的方法
java·开发语言·数据库·sql·oracle
JavaPub-rodert12 小时前
王仕宇在 Go Context 如何解决协程泄漏与超时控制
开发语言·后端·golang·iphone·javapub·王仕宇
ly768913 小时前
JavaScript 从入门到进阶:核心语法、异步编程与工程化实践
开发语言·javascript·ecmascript
落魄大学生之流水线上谋生计14 小时前
Java锁全面指南:从基础概念到企业级应用
java·开发语言
for_ever_love__14 小时前
python基础语法学习: 闭包
开发语言·python·学习·闭包
ly768914 小时前
Python 全面入门:从核心语法到工程实践
开发语言·python
艾伦_耶格宇15 小时前
【AI】-4 OpenCode Go 接入 Obsidian 完整指南
运维·开发语言·人工智能·agent·opencode
旋生万物16 小时前
【终极实战】用Python从零“生成“一个宇宙:螺旋干涉模型的代码实现
开发语言·前端·人工智能·react.js·php·wpf