Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a parameter to a pytest fixture?

Tags:

python

pytest

I would like to pass in an argument to my pytest fixture so I don't need 10 different fixtures when the fixtures are 90% the same.

The simplest example of what I'd like to achieve:

@pytest.mark.parametrize('foo', [a=1])
def test_args(tmp_path, foo):
    assert foo == 3

@pytest.fixture
def foo(tmp_path, a, b=2):
    return a + b

Is there a way to mark a and b as arguments and not other fixtures? Or maybe the best way to do this is somehow by defining a function instead of a fixture?

I put the tmp_path fixture in there to ensure the parametrization is explicit and allows for more than one fixture to be used.

It's worth pointing out that

@pytest.fixture
def foo(request):
    return request.param[0] + request.param[1]


@pytest.mark.parametrize('foo', [(1, 2)], indirect=True)
def test_args(tmp_path, foo):
    assert foo == 3

works, (as defined in the docs), but is not what I'm looking for. I'm wondering if something more similar to my given code will work. I'd like to be able to pass arguments by name, specify default values for arguments, etc.

I've seen this similar stackoverflow question, which seems to indicate that this feature is supported by pytest(?), but its answers seem to just further confusion and none of them seem to work for the case I presented.

like image 258
Jacob Pavlock Avatar asked Mar 02 '23 04:03

Jacob Pavlock


1 Answers

I was able to achieve what I wanted with fixture factories

@pytest.fixture
def foo(tmp_path):
    def _foo(a: int, b: int = 2):
        return a + b

    return _foo

def test_args(tmp_path, foo):
    bar = foo(a=1)
    assert bar == 3
like image 54
Jacob Pavlock Avatar answered Mar 05 '23 17:03

Jacob Pavlock