Pytest精通指南(19)断言和异常处理

本文介绍了pytest框架中的assert关键字用于断言代码行为,以及pytest.raises()用于验证预期的异常。内容涵盖了assert的应用场景、测试结果、基本用法,以及pytest.raises()的功能、区别和使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



请添加图片描述

Pytest assert 简介

断言(Assertion)是编程中的一个基本概念,用于验证程序中的某个条件是否为真。

在单元测试中,断言是验证代码行为是否符合预期的主要手段。如果断言的条件不满足(即为假),则测试失败,通常会导致程序抛出AssertionError异常。

pytest测试框架中,assert是进行断言的核心机制;它依赖于Python内置的assert关键字。
assert语句中的表达式求值为False时,测试将失败,并且程序执行将立即停止,assert语句之后的代码将不会被执行。

assert 应用场景

pytest的assert断言在各种测试场景中都有广泛应用,包括但不限于:

  • 函数或方法的返回值验证;
  • 数据结构或对象状态的验证;
  • 异常处理的验证;
  • 接口的响应验证;
  • 数据库操作结果的验证等。

assert 测试结果

pytest执行测试用例时,它会根据assert断言的结果来判断测试是否通过。

  • 如果断言成功,则测试通过;
  • 如果断言失败,则测试失败,终止后续代码的执行,并显示相应的错误信息。

assert 基本用法

使用语法:

  • assert 表达式
  • assert 表达式, 描述
  • 如果断言失败,描述作为AssertionError的内容展示

示例代码

def add(x, y):
    return x + y


def test_case_01():
    print("进入测试函数")
    assert add(2, 3) == 5
    print("断言成功")


def test_case_02():
    print("进入测试函数")
    assert add(2, 3) == 10
    print("断言失败")  # 不会被执行


def test_case_03():
    print("进入测试函数")
    # 带描述性错误消息的用法
    assert add(2, 3) == 10, "结果与预期不符"
    print("断言失败")  # 不会被执行

执行结果

在这里插入图片描述

Pytest raises 简介

pytest.raises() 是一个内建于 pytest 测试框架中的上下文管理器;

它允许我们在编写单元测试时断言某个特定的异常会被抛出。

当代码块中抛出了预期的异常时,pytest.raises() 会捕获该异常,并且测试会继续进行。

如果没有抛出异常,或者抛出了不同类型的异常,测试将会失败。

raises 用途和作用

  • 断言异常类型:我们可以使用 pytest.raises() 来断言某个函数或方法会抛出特定类型的异常。
  • 获取异常细节:通过 pytest.raises(),我们可以访问被捕获的异常实例,从而获取异常的详细信息,比如异常类型、异常信息(message)等。
  • 匹配异常信息pytest.raises() 支持使用 match 参数来指定一个正则表达式,该表达式用于匹配异常信息。如果异常信息符合该正则表达式,测试会通过。
  • 异常处理后的代码不会执行:当 pytest.raises() 捕获到异常后,该异常之后的代码块将不会执行。这与标准的 try...except 块的行为是一致的。

raises 与 try 的区别

直接使用 try…except 捕捉异常的区别:

  • 断言性pytest.raises() 是一个断言,它明确指出了测试失败的条件,即没有抛出预期的异常或抛出了错误的异常类型。而 try...except 只是简单地捕获异常,并不直接表明测试是否通过。
  • 报告pytest 会自动报告哪些测试失败,并显示失败的原因,包括未抛出的异常或异常类型不匹配等。而使用 try...except,你可能需要手动添加更多的逻辑来报告测试状态。
  • 可读性pytest.raises() 的语法更加清晰,它直接指出了期望抛出的异常类型,以及可能的异常信息。而 try...except 需要更多的上下文来理解测试的意图。
  • 灵活性pytest.raises() 提供了更多的选项,比如 match 参数可以用来匹配异常信息。而 try...except 则需要额外的逻辑来处理这些信息。
  • 集成性pytest.raises()pytest 测试框架完美集成,你可以利用 pytest 的其他功能,如参数化测试、测试固件(fixtures)等。而 try...except 只是一个 Python 的基础语法结构,没有与测试框架的深度集成。

python代码中使用try

示例代码

print("测试开始")
try:
    a = int(input("请输入被除数:"))
    b = int(input("请输入除数:"))
    res = a / b
    print(f"res={res}")
except ValueError as e1:
    print("格式异常:", e1)
except ZeroDivisionError as e2:
    print("被除数异常:", e2)
except ArithmeticError as e3:
    print("算数异常:", e3)
except Exception as e4:
    print("意外异常:", e4)
print("测试完成")

执行结果

在这里插入图片描述

在测试用例中使用try

示例代码

def test_case_01():
    print("测试开始")
    try:
        a = int(input("请输入被除数:"))
        b = int(input("请输入除数:"))
        res = a / b
        print(f"res={res}")
    except ValueError as e1:
        print("格式异常:", e1)
    except ZeroDivisionError as e2:
        print("被除数异常:", e2)
    except ArithmeticError as e3:
        print("算数异常:", e3)
    except Exception as e4:
        print("意外异常:", e4)
    print("测试完成")

执行结果

在这里插入图片描述

使用pytest.raises()

示例代码

import pytest


# 捕捉指定异常:哪怕with下面的代码发生了ZeroDivisionError类型的异常,整个用例不会认为是异常用例,认为是正常的
def test_case_01():
    with pytest.raises(ZeroDivisionError):
        res = 10 / 0
        print('结果:', res)  # 上述代码抛出异常后,不会继续执行后续代码


# 捕捉多个异常,如果实际代码中抛出的异常是其中一个则认为测试用例通过
def test_case_02():
    with pytest.raises(expected_exception=(ValueError, ZeroDivisionError)):
        raise ZeroDivisionError("除数为0")


# 利用match参数使用正则表达式
def test_case_03():
    with pytest.raises(ValueError, match='自定义错误'):
        raise ValueError("自定义错误:xxxx发生了意外")


# 利用match参数使用正则表达式,如果异常信息中包含xxxx则认为测试用例通过
def test_case_04():
    with pytest.raises(ValueError, match=r'.*xxxx.*'):
        raise ValueError("自定义错误:xxxx发生了意外")


# 没有预期的异常就报错,同时,后面的代码不会被执行
def test_case_05():
    with pytest.raises(ZeroDivisionError):
        print("这句代码会被执行")
        raise ValueError("数据异常")
    print("这句代码不会被执行")


# 获取捕获的异常的细节(异常类型, 异常信息)
def test_case_06():
    with pytest.raises(ValueError) as exc_info:
        raise ValueError("数据异常")
    assert exc_info.type is ValueError
    assert exc_info.value.args[0] == "数据异常xxx"

执行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要休息的KK.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值