web-dev-qa-db-ja.com

複数の例外を除いてpytest.raisesを使用するにはどうすればよいですか?

次の2つの例外のいずれかが発生する可能性があるコードをテストしています: MachineError またはNotImplementedError。 pytest.raisesを使用して、テストコードの実行時に少なくとも1つが発生することを確認したいのですが、引数として1つの例外タイプしか受け入れないようです。

これは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.raisesNoneであるかどうかをチェックし、そうである場合は2番目をコンテキストマネージャーとして設定すると思います。

pytest.raisesは2番目の引数を呼び出し可能にするため、複数の例外を位置引数として渡すことはできません。後続のすべての位置引数は、その呼び出し可能オブジェクトへの引数として渡されます。

ドキュメント から:

>>> 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'>

これに対する回避策はありますか?コンテキストマネージャーを使用する必要はありません。

17
fenceop

例外をタプルとしてraisesに渡します。

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

pytestのソースでは、pytest.raises 五月:

Python 3、 exceptステートメント では、例外のタプルを取ることができます。issubclass関数 また、タプル 。したがって、タプルの使用はどちらの状況でも許容できるはずです。

32
cxw