pytest: parameterize a test via loaded cfg file which has the name of the current test name

59 views Asked by At

I would like to create a test that uses input parameters. The parameters exist in a configuration file (cfg) under my project. It is important to look for a cfg file with the same name as the current test to be run. In a function (under a fixture), I can obtain the cfg file's content (using the file name from another fixture: request.node.name). How can I use this content to parameterize a test?

So, the basic way of parametrizing a test looks like that:

@pytest.mark.parametrize("input,expected", [(param1, param2)])
def test_example(input, expected):
    # How to access cfg data here?

Unfortunately, the cfg content is unreachable for this @pytest.mark.parametrize decorator. Here is a fixture in conftest.py that returns the cfg content:

@pytest.fixture(scope="function")
def cfg_data(request):
    cfg_name = F'{request.node.name}.cfg'
    cfg_template_dir = eval(settings.cfg_tests_folder)
    cfg_template_file = Path(cfg_template_dir).joinpath(cfg_name)
    with open(cfg_template_file, 'r') as cfg_data:
        cfg_data_dict = yaml.safe_load(cfg_data)
        return cfg_data_dict

I would like to parameterize the following test, using the cfg content as parameters:

def test1(cfg_data, tests_client, settings_data):
    tests_client.load_data(settings_data.csv_file_name)
    # Perform test with cfg_data as parameters

Another thing which might help; Is there anyway to have the fixture out of the test's scope (or within the ClassTest - then it can be used in a test under this class)?

Thank you!

''' thank you for your answer. Following your post, I've implemented it like that: '''

# load all args which required only for the parametrized tests
def load_test_params(test_name) -> object:
    test_name = test_name.split('[')[0]
    cfg_name = F'{test_name}.cfg'
    cfg_template_dir = eval(settings.cfg_tests_folder)
    cfg_template_file = Path(cfg_template_dir).joinpath(cfg_name)
    if cfg_template_file.exists():
        with open(cfg_template_file, 'r') as cfg_data:
            cfg_data_dict = yaml.safe_load(cfg_data)
            return cfg_data_dict

def pytest_generate_tests(metafunc):
    """
    generate the parametrized args which required for the parametrized tests.
    :param metafunc: pytest built-in function
    """
    fct_name = metafunc.function.__name__
    if fct_name.startswith('test_param'):
        parameterized_data = load_test_params(fct_name)
        if parameterized_data.get(fct_name):
            params = parameterized_data[fct_name]
            metafunc.parametrize(params["params"], params["values"])
0

There are 0 answers