Pytest parametrized dependency

1.3k Views Asked by At

I have a function and a test

def foo(a):
    return bar(a)

@pytest.mark.parametrize(
  'number',
    [1,2,3]
)
@pytest.mark.dependency
def test_foo(number):
    assert foo(number) > SOME_CONST # Simplistic example, real case is more nuanced

I'm using pytest and the pytest_dependency module. foo is a function used in a number of other tests. I have a function which I want to play a dependency on test_foo, the code below doesn't work:

@pytest.mark.dependency(depends=['test_foo'])
@pytest.mark.parametrize(
    'param',
    itertools.permutations(['a','b','c','d','e'],2),
    ids=repr,
)

def test_bar(param):
    ...
    important_result = foo(param)
    ...

The theory is that if test_foo fails, then test_bar will be skipped. However, when I parametrize test_bar, each instantiation of test_bar is skipped regardless of the result of test_foo.

To clarify, this code works as expected (test_bar is not skipped):

@pytest.mark.dependency(depends=['test_foo'])
def test_bar():
    param = some_fnc(['a', 'b'])
    ...
    important_result = foo(param)
    ...
1

There are 1 best solutions below

0
On

Your problem has to do with the node_id assigned to each test by pytest (see pytest-dependency#names).

Based on your question, I understand you want test_bar to depend on all the parametrizations of test_foo, so in that case you need to do:

@pytest.mark.dependency(depends=['foo[1]', 'foo[2]', 'foo[3]'])
@pytest.mark.parametrize(
    'param',
    itertools.permutations(['a', 'b', 'c', 'd', 'e'], 2),
    ids=repr,
)
def test_bar(param):
    ...

But since the parametrization can be more complex than just a number, it is advisable to implement the following approach:

@pytest.mark.parametrize(
    'number',
    [
        pytest.param(1, marks=pytest.mark.dependency(name='foo1')),
        pytest.param(2, marks=pytest.mark.dependency(name='foo2')),
        pytest.param(3, marks=pytest.mark.dependency(name='foo3'))
    ]
)
def test_foo(number):
    ...


@pytest.mark.dependency(depends=['foo1', 'foo2', 'foo3'])
@pytest.mark.parametrize(
    'param',
    itertools.permutations(['a', 'b', 'c', 'd', 'e'], 2),
    ids=repr,
)
def test_bar(param):
    ...

If you want a dependency per parametrization instead, you will have to explicitly set the dependency of each param value in test_bar to its corresponding foo? test.