2
votes

Trying to set an option in a pytest.ini file dynamically. The option testpaths determines what directories pytest will gather tests from. I want to give users the ability to select test directory a or b.

conftest.py

The first hook creates a parser option. The second hook pulls the parser option reads the value and adds the testpath to the testpaths option under the config object.

@pytest.hookimpl() 
def pytest_addoption(parser):
    """Creates a parser option"""

    # Allows the user to select the test suite they want to run
    parser.addoption("--suite", action="store", default="None"
                     , choices=['a', 'b']
                     , help="Choose which test suite to run.")

@pytest.hookimpl()
def pytest_configure(config):
    print("Determining test directory")
    suite = config.getoption("--suite")

    if suite == "a":
        config.addinivalue_line("testpaths", "tests/a")

    elif suite == "b":
        config.addinivalue_line("testpaths", "tests/b")

So if i run pytest --suite a it should load all tests under the a test suite. It does not. It loads all tests like the option doesnt exist.

1

1 Answers

2
votes

The value is being set correctly. Your problem is that at the time pytest_configure hooks are being called, the ini file values and the command line args are already parsed, so adding to the ini values will not bring anything - they won't be read again anymore. In particular, the testpaths value from ini file is already processed and stored in config.args. So we can overwrite config.args instead:

@pytest.hookimpl()
def pytest_configure(config):
    suite = config.getoption('--suite')

    if suite == 'a':
        config.args = ['tests/a']
    elif suite == 'b':
        config.args = ['tests/b']

Edit

An example of accessing the config in your tests (via pytestconfig fixture):

def test_spam(pytestconfig):
    print(pytestconfig.getini('testpaths'))
    print(pytestconfig.args)
    suite_testpaths = set(pytestconfig.args) - set(pytestconfig.getini('testpaths'))
    print('testpaths that were added via suite arg', suite_testpaths)