Search code examples
pytestfixturesparameterization

How to force Pytest to execute the only function in parametrize?


I have 2 tests. I want to run the only one:

pipenv run pytest -s tmp_test.py::test_my_var

But pytest executes both functions in @pytest.mark.parametrize (in both tests)

How can I force Pytest to execute the only get_my_var() function if I run the only test_my_var?

If I run the whole file:

pipenv run pytest -s tmp_test.py

I want Pytest to execute the code in the following manner:

get_my_var()
test_my_var()
get_my_var_1()
test_my_var_1()

Actually, my functions in @pytest.mark.parametrize make some data preparation and both tests use the same entities. So each function in @pytest.mark.parametrize changes the state of the same test data.

That's why I strongly need the sequential order of running parametrization functions just before corresponding test.

def get_my_var():
    with open('my var', 'w') as f:
        f.write('my var')
    return 'my var'


def get_my_var_1():
    with open('my var_1', 'w') as f:
        f.write('my var_1')
    return 'my var_1'


@pytest.mark.parametrize('my_var', get_my_var())
def test_my_var(my_var):
    pass


@pytest.mark.parametrize('my_var_1', get_my_var_1())
def test_my_var_1(my_var_1):
    pass

Or how can I achive the same goal with any other options?

For example, with fixtures. I could use fixtures for data preparation but I need to use the same fixture in different tests because the preparation is the same. So I cannot use scope='session'.

At the same time scope='function' results in fixture runs for every instance of parameterized test.

Is there a way to run fixture (or any other function) the only one time for parameterized test before runs of all parameterized instances?


Solution

  • It looks like that only something like that can resolved the issue.

    import pytest
    
    current_test = None
    
    
    @pytest.fixture()
    def one_time_per_test_init(request):
        test_name = request.node.originalname
        global current_test
        if current_test != test_name:
            current_test = test_name
            init, kwargs = request.param
            init(**kwargs)