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"]
相关推荐
布朗克1681 小时前
12 封装与构造方法
java·开发语言·封装·构造方法
z落落1 小时前
C# 抽象类(abstract)
java·开发语言·c#
折哥的程序人生 · 物流技术专研1 小时前
AI 编程与行业赋能|专栏总目录(持续更新)
开发语言·人工智能·软件工程·ai编程
SilentSamsara1 小时前
爬虫工程化:Playwright + 反反爬 + 数据清洗管道实战
开发语言·爬虫·python·青少年编程·playwright
AI玫瑰助手1 小时前
Python函数:函数的返回值(return)与多值返回
开发语言·python·信息可视化
花果山~~程序猿1 小时前
快速认识python项目的虚拟环境
开发语言·python
basketball6161 小时前
Go语言从入门到进阶:8. 接口
开发语言·后端·golang
gCode Teacher 格码致知1 小时前
Python教学:字符编码的四种环境-由Deepseek产生
开发语言·python
铁链鞭策大师1 小时前
JavaEE之多线程
java·开发语言·java-ee