Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pytest using fixtures as arguments in parametrize

Tags:

python

pytest

I would like to use fixtures as arguments of pytest.mark.parametrize or something that would have the same results.

For example:

import pytest import my_package  @pytest.fixture def dir1_fixture():     return '/dir1'  @pytest.fixture def dir2_fixture():     return '/dir2'  @pytest.parametrize('dirname, expected', [(dir1_fixture, 'expected1'), (dir2_fixture, 'expected2')] def test_directory_command(dirname, expected):     result = my_package.directory_command(dirname)     assert result == expected 

The problem with fixture params is that every param of the fixture will get run every time it's used, but I don't want that. I want to be able to choose which fixtures will get used depending on the test.

like image 285
elveatles Avatar asked Feb 02 '17 23:02

elveatles


People also ask

Can we use fixture in Parametrize pytest?

Being able to reuse fixtures in parametrized tests is a must when we want to avoid repetition. Unfortunately, pytest doesn't support that yet. On the other hand, we can make it happen either by using getfixturevalue in pytest or through a third-party library.

Can fixtures be parameterized?

fixture() allows one to parametrize fixture functions.

How does pytest Parametrize work?

pytest will build a string that is the test ID for each set of values in a parametrized test. These IDs can be used with -k to select specific cases to run, and they will also identify the specific case when one is failing. Running pytest with --collect-only will show the generated IDs.


2 Answers

If you're on pytest 3.0 or later, I think you should be able to solve this particular scenario by writing a fixture along the lines of:

@pytest.fixture(params=['dir1_fixture', 'dir2_fixture']) def dirname(request):     return request.getfixturevalue(request.param) 

Docs here: http://doc.pytest.org/en/latest/builtin.html#_pytest.fixtures.FixtureRequest.getfixturevalue

However, you can't use this approach if the fixture you're attempting to dynamically load is parametrized.

Alternatively, you might be able to figure something out with the pytest_generate_tests hook. I haven't been able to bring myself to look into that much, though.

like image 193
Will Avatar answered Sep 19 '22 20:09

Will


Will was on the right path, you should use request.getfixturevalue to retrieve the fixture.

But you can do it right in the test, which is simpler.

@pytest.mark.parametrize('dirname, expected', [     ('dir1_fixture', 'expected1'),     ('dir2_fixture', 'expected2')]) def test_directory_command(dirname, expected, request):     result = my_package.directory_command(request.getfixturevalue(dirname))     assert result == expected 

Another way is to use lazy-fixture plugin:

@pytest.mark.parametrize('dirname, expected', [     (pytest.lazy_fixture('dir1_fixture'), 'expected1'),     (pytest.lazy_fixture('dir2_fixture'), 'expected2')]) def test_directory_command(dirname, expected):     result = my_package.directory_command(dirname)     assert result == expected 
like image 25
ggguser Avatar answered Sep 23 '22 20:09

ggguser