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"])