如何使用pytest.raises多个例外?

时间:2016-07-15 19:23:35

标签: exception python-3.4 pytest contextmanager

我正在测试代码,其中可以引发两个异常中的一个: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'>

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

1 个答案:

答案 0 :(得分:21)

将例外作为元组传递给raises

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

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

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