Reputation: 169
My use case is to call fixture only if a certain condition is met. But since we need to call the pytest fixture as an argument to a test function it gets called every time I run the test.
I want to do something like this:
@pytest.parameterize("a", [1, 2, 3])
def test_method(a):
if a == 2:
method_fixture
Upvotes: 5
Views: 6914
Reputation: 3879
The answer is accepted and helped for the OP however it is not "conditional fixture calling". It is called always only it behaves differently based on some condition.
So I only want to clarify that real conditionally call (or dynamically run) a fixture is possible using the request
fixture.
@pytest.parameterize("a", [1, 2, 3])
def test_method(request, a):
if a == 2:
request.getfixturevalue('method_fixture')
See documentation here https://docs.pytest.org/en/7.1.x/reference/reference.html#pytest.FixtureRequest.getfixturevalue
Upvotes: 13
Reputation: 168957
Yes, you can use indirect=True
for a parameter to have the parameter refer to a fixture.
import pytest
@pytest.fixture
def thing(request):
if request.param == 2:
return func()
return None
@pytest.mark.parametrize("thing", [1, 2, 3], indirect=True)
def test_indirect(thing):
pass # thing will either be the retval of `func()` or NOne
As asked in the edit, if your fixtures are dependent on each other, you'll probably need to use the pytest_generate_tests
hook instead.
E.g. this will parametrize the test with values that aren't equal.
import itertools
def pytest_generate_tests(metafunc):
if metafunc.function.__name__ == "test_combo":
a_values = [1, 2, 3, 4]
b_values = [2, 3, 4, 5]
all_combos = itertools.product(a_values, b_values)
combos = [
pair
for pair in all_combos
if pair[0] != pair[1]
]
metafunc.parametrize(["a", "b"], combos)
def test_combo(a, b):
assert a != b
Upvotes: 4