Reputation: 1337
Pytest does not catch StopIteration errors with pytest.raises
.
As an example this fails:
def test_stop_iteration():
def iterthis():
for i in range(5):
yield i
raise StopIteration("FINISHED")
model = iterthis()
next(model)
next(model)
next(model)
next(model)
next(model)
with pytest.raises(StopIteration):
next(model)
But this passes:
def test_stop_iteration():
def iterthis():
for i in range(5):
yield i
raise StopIteration("FINISHED")
model = iterthis()
next(model)
next(model)
next(model)
next(model)
next(model)
with pytest.raises(Exception):
next(model)
Am I missing something here?
Upvotes: 1
Views: 954
Reputation: 16815
This is covered in the documentation:
If a generator code directly or indirectly raises StopIteration, it is converted into a RuntimeError (retaining the StopIteration as the new exception’s cause).
So, if you really need to catch it this way, you have to catch RuntimeError
instead:
with pytest.raises(RuntimeError) as e:
next(model)
assert "StopIteration" in str(e.value)
The exception also contains the message "generator raised StopIteration" as the cause, so you can check for that.
Note that this behavior is specific to generators. If you would just raise a StopIteration
outside of a generator it would behave like any other exception:
def test_stop_iteration():
def raise_stopiter():
raise StopIteration("FINISHED")
with pytest.raises(StopIteration):
raise_stopiter()
Upvotes: 4