I would like to know if there is a better way and what the options are for testing raise X from Y
using pytest.
Here's a dummy example:
import pytest
class AException(Exception):
pass
class A:
def __init__(self) -> None:
raise AException("Class A")
class C:
def __init__(self) -> None:
try:
A()
except AException as err:
raise ValueError("C Failed") from err
def test_class_c():
with pytest.raises(ValueError):
C()
In this example, the test should confirm that it raised ValueError
from AException
from Class A
.
The obvious solution is to pass the message like this:
except AException as err:
raise ValueError(f"C Failed: {err}") from err
and then match it:
def test_class_c():
with pytest.raises(ValueError, match="Class A"):
C()
but is there another way?
CodePudding user response:
I haven't come across an official way of doing this but one way could be to check __cause__
(or __context__
) of the most "recent" exception:
def test_class_c():
with pytest.raises(ValueError) as exc_info:
C()
assert isinstance(exc_info.value.__cause__, AException)
assert exc_info.value.__cause__.args == ("Class A",)
PEP regarding __cause__
and __context__
: https://www.python.org/dev/peps/pep-3134/