pytest 测试框架学习(11):pytest.raises

本文深入解析pytest.raises的功能,演示如何在测试中捕获预期异常,包括使用match进行自定义异常匹配,以及通过上下文管理器获取异常详细信息。同时,介绍了pytest.mark.parametrize结合does_not_raise的用法。

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

pytest.raises

含义

raises: 在断言一些代码块或者函数时会引发意料之中的异常或者其他失败的异常,导致程序无法运行时,使用 raises 捕获匹配到的异常,可以继续让代码正常运行。
源码:
在这里插入图片描述
expected_exception: 预期的异常(可以输入一个元组)。

使用

  1. 预期内异常
import pytest

def test_raises():
    with pytest.raises(ZeroDivisionError):
        2 / 0
    assert eval("1 + 2") == 3

raises 可以捕获到该异常,并继续下面断言代码。

  1. 如果我们不知道预期异常的是什么,我们可以使用 matchraise 进行自定义异常
import pytest

def exc(x):
    if x == 0:
        raise ValueError("value not 0 or None")
    return 2 / x

def test_raises():
    with pytest.raises(ValueError, match="value not 0 or None"):
        exc(0)
    assert eval("1 + 2") == 3

match 还可以使用正则表达式进行匹配异常:

with pytest.raises(ValueError, match=r"value not \d+$"):
	raise ValueError("value not 0")

Tips: 使用正则时,等号后面有个 r 。

  1. 在捕获异常后,可以从上下文管理器中获取异常的一些详细信息,可以辅助我们更好的去断言。
import pytest

def exc(x):
    if x == 0:
        raise ValueError("value not 0")
    return 2 / x

def test_raises():
    with pytest.raises(ValueError) as exec_info:
        exc(0)

    print("exec_info.type = ", exec_info.type)
    print("exec_info.value.args = ", exec_info.value.args)

    assert exec_info.type == ValueError
    assert exec_info.value.args[0] == "value not 0"

执行结果:
在这里插入图片描述

注意: 官方提示, raise 的异常应该是当前代码块最后一行,如果在其后面还有代码,那么将不会被执行。比如:
在这里插入图片描述
修改后代码
在这里插入图片描述

  1. 参数化 pytest.mark.parametrize
    使用参数化的话,可能会存在一部分用例可能会抛出异常,一部分可能会没有异常导致失败。如果想要其正常执行,则需要一个上下文管理器。这里官方指导使用 does_not_raise
    例:
from contextlib import contextmanager
import pytest

@contextmanager
def does_not_raise():
    yield

@pytest.mark.parametrize(
    "example_input,expectation",
    [
        (3, does_not_raise()),
        (2, does_not_raise()),
        (1, does_not_raise()),
        (0, pytest.raises(ZeroDivisionError)),
    ],
)
def test_division(example_input, expectation):
    """Test how much I know division."""
    with expectation:
        assert (6 / example_input) is not None

注意: 如果使用的python版本不一致,导入对应依赖也是不一样的。
python3.7+: from contextlib import nullcontext as does_not_raise
python3.3+: from contextlib import ExitStack as does_not_raise
或者使用 pip install contextlib2
from contextlib2 import nullcontext as does_not_raise

以下两个为拓展形式,但 官方建议不使用。因为上面形式的可读性会更强。

  1. lambda 表达式
import pytest

pytest.raises(ZeroDivisionError, lambda: 1/0)
  1. 指定函数,并调用可用参数
import pytest

def exc(x):
    return 2 / x

def test_raises_param():
    pytest.raises(ZeroDivisionError, exc, x=0)
    assert 1 == 1

说明:本篇参考官网并加入自己些许理解翻译而来,觉得有用,可以点赞和赞赏哦(^ v ^),谢谢支持;如果有不足地方,可留言评论。后续将继续更新。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值