Search code examples
pytestassertfixtureshardcodedparametrized-testing

Function in pytest file works only with hard coded values


I have the below test_dss.py file which is used for pytest:

import dataikuapi

import pytest
 

def setup_list():

    client = dataikuapi.DSSClient("{DSS_URL}", "{APY_KEY}")

    client._session.verify = False

    project = client.get_project("{DSS_PROJECT}")

    # Check that there is at least one scenario TEST_XXXXX & that all test scenarios pass

    scenarios = project.list_scenarios()

    scenarios_filter = [obj for obj in scenarios if obj["name"].startswith("TEST")]

    return scenarios_filter

 
def test_check_scenario_exist():

    assert len(setup_list()) > 0, "You need at least one test scenario (name starts with 'TEST_')"

 
@pytest.mark.parametrize("scenario", setup_list())

def test_scenario_run(scenario, params):

    client = dataikuapi.DSSClient(params['host'], params['api'])

    client._session.verify = False

    project = client.get_project(params['project'])

    scenario_id = scenario["id"]

    print("Executing scenario ", scenario["name"])

    scenario_result = project.get_scenario(scenario_id).run_and_wait()

    assert scenario_result.get_details()["scenarioRun"]["result"]["outcome"] == "SUCCESS", "test " + scenario[

    "name"] + " failed"

My issue is with setup_list function, which able to get only hard coded values for {DSS_URL}, {APY_KEY}, {PROJECT}. I'm not able to use PARAMS or other method like in test_scenario_run any idea how I can pass the PARAMS also to this function?


Solution

  • The parameters in the mark.parametrize marker are read at load time, where the information about the config parameters is not yet available. Therefore you have to parametrize the test at runtime, where you have access to the configuration.

    This can be done in pytest_generate_tests (which can live in your test module):

    @pytest.hookimpl
    def pytest_generate_tests(metafunc):
        if "scenario" in metafunc.fixturenames:
            host = metafunc.config.getoption('--host')
            api = metafuc.config.getoption('--api')
            project = metafuc.config.getoption('--project')
            metafunc.parametrize("scenario", setup_list(host, api, project))
    

    This implies that your setup_list function takes these parameters:

    def setup_list(host, api, project):
        client = dataikuapi.DSSClient(host, api)
        client._session.verify = False
        project = client.get_project(project)
        ...
    

    And your test just looks like this (without the parametrize marker, as the parametrization is now done in pytest_generate_tests):

    def test_scenario_run(scenario, params):
        scenario_id = scenario["id"]
        ...
    

    The parametrization is now done at run-time, so it behaves the same as if you had placed a parametrize marker in the test.

    And the other test that tests setup_list now has also to use the params fixture to get the needed arguments:

    def test_check_scenario_exist(params):
        assert len(setup_list(params["host"], params["api"], params["project"])) > 0,
     "You need at least ..."