Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional argument in pytest.mark.parametrize

I have a long test with pytest framework. The code is like this:

@pytest.fixture(scope='function')
def my_setup():
        execute_setup_actions()

@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine(name, arg1):
         execute_test_case(arg1)

Now I need an optional argument arg2 for my_setup fixture my_setup(arg2=None) used in one new test written in @pytest.mark.parametrize. Certainly I can put 'name, arg1, arg2' in parametrize and add None argument values for other 100 tests, but is there any other method to do such a thing in a more pretty way?

Thanks!

like image 507
andrey_Kox Avatar asked May 02 '26 07:05

andrey_Kox


1 Answers

The most standard (i.e. canonical) way of passing parameters into fixtures is to use pytest's indirect arguments.

You can either add this new argument to all parameters tuples, or if you wish to avoid it, you can create a new test method that is identical to the first method, but it would only contain the new tuples, like so:

import pytest


def execute_setup_actions(fixture_param):
    print(f"entered execute_setup_actions with {fixture_param}")


@pytest.fixture(scope='function')
def my_setup(request):
    fixture_param = getattr(request, 'param', None)  # or your default value
    execute_setup_actions(fixture_param)
    return fixture_param


def execute_test_case(arg1, arg2):
    print(f"entered execute_test_case with {arg1}, {arg2}")


@pytest.mark.parametrize('name, arg1', [
    ('test_1', 1),
    ('test_100', 100),
])
def test_mine(my_setup, name, arg1):
    execute_test_case(arg1, my_setup)


@pytest.mark.parametrize('my_setup, name, arg1', [
    (20, 'test_101', 1),
    (2020, 'test_102', 100),
], indirect=["my_setup"])
def test_mine_with_extra_parameter(my_setup, name, arg1):
    execute_test_case(arg1, my_setup)
like image 106
Peter K Avatar answered May 04 '26 22:05

Peter K