如何使用 pytest.raises 有多个异常?

Posted

技术标签:

【中文标题】如何使用 pytest.raises 有多个异常?【英文标题】:How can I use pytest.raises with multiple exceptions? 【发布时间】:2016-11-19 02:42:09 【问题描述】:

我正在测试可以引发以下两个异常之一的代码:MachineError 或 NotImplementedError。我想使用pytest.raises 来确保在我运行测试代码时至少引发其中一个,但它似乎只接受一种异常类型作为参数。

这是pytest.raises的签名:

raises(expected_exception, *args, **kwargs)

我尝试在上下文管理器中使用 or 关键字:

with pytest.raises(MachineError) or pytest.raises(NotImplementedError):
    verb = Verb("donner<IND><FUT><REL><SG><1>")
    verb.conjugate()

但我假设这只会检查第一个 pytest.raises 是否为 None,如果是,则将第二个设置为上下文管理器。

将多个异常作为位置参数传递是行不通的,因为pytest.raises 将其第二个参数作为可调用参数。每个后续的位置参数都作为参数传递给该可调用对象。

来自documentation:

>>> raises(ZeroDivisionError, lambda: 1/0)
<ExceptionInfo ...>

>>> def f(x): return 1/x
...
>>> raises(ZeroDivisionError, f, 0)
<ExceptionInfo ...>
>>> raises(ZeroDivisionError, f, x=0)
<ExceptionInfo ...>

将异常作为列表传递也不起作用:

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    with pytest.raises([MachineError, NotImplementedError]):
  File "/usr/local/lib/python3.4/dist-packages/_pytest/python.py", line 1290, in raises
    raise TypeError(msg % type(expected_exception))
TypeError: exceptions must be old-style classes or derived from BaseException, not <class 'list'>

有解决办法吗?它不必使用上下文管理器。

【问题讨论】:

您是否尝试将多个异常作为位置参数或元组传递给 raise? @jonrsharpe 我尝试使用列表而不是元组传递多个异常。 cxw's answer 工作。 【参考方案1】:

将异常作为元组传递给raises

with pytest.raises( (MachineError, NotImplementedError) ):
    verb = ...

pytest的来源中,pytest.raises可能:

catch expected_exception;或 pass expected_exception to a RaisesContext instance,然后 uses issubclass 检查异常是否是您想要的异常。

在 Python 3 中,except statements 可以接受一组异常。 issubclass 函数 can also take a tuple。因此,在任何一种情况下都可以使用元组。

【讨论】:

知道为什么异常可以作为元组而不是列表传递吗?我阅读了文档,但我不明白为什么不允许列表,即使它们是可迭代的。 @fenceop ***.com/questions/35851782/… 虽然从测试的角度来看,我认为这应该是不允许的。这几乎就像说:断言 1 + 2 == 3 或 4

以上是关于如何使用 pytest.raises 有多个异常?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多个 CSV 文件进行机器学习异常检测

如何使用多个catch块处理异常

如何处理多个异常

如何使用异步等待处理多个异常

Java中有多个异常, 如何确定捕获顺序(多个catch),先从上到下执行,判断异常的大小,如果包含捕到异常,就进入这个catch,后面的就不再执行

如何使用异常条件对多个字段进行排序