0

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"])
ollie
  • 1
  • 1
  • There are a few things I don't understand: (i) How do the `tests_client` and `settings_data` parameters relate to the `cfg_data` parameters? (ii) It looks like there is only a single `cfg_data_dict` for each test function, so is the intent to extract multiple parameters from this one dictionary? – Kale Kundert Jun 18 '23 at 23:14
  • That said, I wrote a package for the exact purpose of parametrizing tests from config files: [Parametrize From File](https://parametrize-from-file.readthedocs.io/en/latest/index.html). It might be useful for what you're trying to do. – Kale Kundert Jun 18 '23 at 23:17
  • hi - thank you. settings_data - has some test's data - you may avoid it. cfg_data contains the parametrized data. I went to https://stackoverflow.com/questions/66906406/parametrizing-multiple-tests-dynamically-in-python/66912556#66912556 (found it at your stackoverflow profile). and managed to solve it – ollie Jun 24 '23 at 12:25

0 Answers0