Since this question was answered, the pytest docs have updated info on this subject that's worth mentioning here.
https://docs.pytest.org/en/6.2.x/example/parametrize.html#parametrizing-conditional-raising
It's similar to some of the other answers, but using parametrize
and a newer builtin nullcontext
that makes the solution really clean.
A potential Python3.7+ only example would look like:
from contextlib import nullcontext as does_not_raise
import pytest
@pytest.mark.parametrize(
"example_input,expectation",
[
(3, does_not_raise()),
(2, does_not_raise()),
(1, does_not_raise()),
(0, pytest.raises(ZeroDivisionError)),
],
)
def test_division(example_input, expectation):
"""Test how much I know division."""
with expectation:
assert (6 / example_input) is not None
Using parametrize
this way makes it possible to combine OP's test cases, like:
@pytest.mark.parametrize(
"example_input,expectation,message",
[
(3, pytest.raises(MyError), ERROR1),
(11, pytest.raises(MyError), ERROR2),
(7, does_not_raise(), None),
],
)
def test_foo(example_input, expectation, message):
with expectation as e:
foo(example_input)
assert message is None or message in str(e)
Doing it this way allows you to test that it did not raise any exception. nullcontext
is meant as a stand in for an optional context manager (pytest.raises
, in this case). It's not actually doing anything, so if you wanted to test that it did NOT raise a specific exception, you should see one of the other answers.