[pytest-dev] Help with parametrized fixtures
Nikolaus Rath
Nikolaus at rath.org
Thu Nov 27 23:22:55 CET 2014
Carl Meyer <carl-faUO1KlGllLR7s880joybQ at public.gmane.org> writes:
> Hi Nikolaus,
>
> On 11/26/2014 01:21 PM, Nikolaus Rath wrote:
>> I have a parametrized fixture foo, and some test cases that use it:
>>
>> @pytest.fixture(params=(1,2,3,4,5))
>> def foo(request):
>> # ...
>> return foo_f
>>
>> def test_1(foo):
>> # ...
>>
>> def test_2(foo):
>> # ....
>>
>> Now, I'd like to add an additional test, but running it only makes sense
>> for some of the fixture parameters. So far I've solved this by providing
>> the parameter value as a fixture attribute and skipping "unsupported" values:
>>
>> @pytest.fixture(params=(1,2,3,4,5))
>> def foo(request):
>> # ...
>> foo_f.param = request.param
>> return foo_f
>>
>> def test_3(foo):
>> if foo.param not in (1,4,5):
>> raise pytest.skip("doesn't make sense")
>>
>> This works, but I don't like it very much because it means that the test
>> suite can never be executed without skipping some tests. I'd rather
>> reserve skipping for cases where the test could in principle be
>> executed, but for some reason cannot work at the moment (e.g. because
>> there's no internet, or a required utility is not installed).
>>
>> Is there a way to solve the above scenario without skipping tests?
>>
>> Ideally, I'd be able to do something like this:
>>
>> @only_for_param((1,4,5))
>> def test_3(foo):
>> ...
>
> I think in order to do this you'll need to use the
> `pytest_generate_tests` hook:
> http://pytest.org/latest/parametrize.html#pytest-generate-tests
Thanks for the link! The following seems to work nicely:
#!/usr/bin/env python3
import pytest
@pytest.fixture()
def bar(request):
s = 'bar-%d' % request.param
print('preparing', s)
return s
def test_one(bar):
pass
def test_two(bar):
pass
test_two.test_with = (2,3)
def pytest_generate_tests(metafunc):
params = (1,2,3,4)
if not 'bar' in metafunc.fixturenames:
return
test_with = getattr(metafunc.function, 'test_with', None)
if test_with:
params = test_with
metafunc.parametrize("bar", params, indirect=True)
Unfortunately, it seems there are several issues with parametrizing
fixtures these way that are probably going to bite me as things get more
complex:
https://bitbucket.org/hpk42/pytest/issue/635
https://bitbucket.org/hpk42/pytest/issue/634
https://bitbucket.org/hpk42/pytest/issue/531
https://bitbucket.org/hpk42/pytest/issue/519
(Maybe mentioning them here gives them more attention :-).
Best,
-Nikolaus
--
GPG encrypted emails preferred. Key id: 0xD113FCAC3C4E599F
Fingerprint: ED31 791B 2C5C 1613 AF38 8B8A D113 FCAC 3C4E 599F
»Time flies like an arrow, fruit flies like a Banana.«
More information about the pytest-dev
mailing list