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

2020-09-08 11:15:55 浏览数 (1)

pytest.raises

  • 含义
  • 使用

含义

raises: 在断言一些代码块或者函数时会引发意料之中的异常或者其他失败的异常,导致程序无法运行时,使用 raises 捕获匹配到的异常,可以继续让代码正常运行。 源码:

expected_exception: 预期的异常(可以输入一个元组)。

使用

  1. 预期内异常
代码语言:javascript复制
import pytest

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

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

  1. 如果我们不知道预期异常的是什么,我们可以使用 matchraise 进行自定义异常
代码语言:javascript复制
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 还可以使用正则表达式进行匹配异常:

代码语言:javascript复制
with pytest.raises(ValueError, match=r"value not d $"):
	raise ValueError("value not 0")

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

  1. 在捕获异常后,可以从上下文管理器中获取异常的一些详细信息,可以辅助我们更好的去断言。
代码语言:javascript复制
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 例:
代码语言:javascript复制
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 表达式
代码语言:javascript复制
import pytest

pytest.raises(ZeroDivisionError, lambda: 1/0)
  1. 指定函数,并调用可用参数
代码语言:javascript复制
import pytest

def exc(x):
    return 2 / x

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

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

0 人点赞