Gunnar
Gunnar

Reputation: 113

Py.test: Run initialization method before pytest_generate_tests

I'm making a test suite using py.test that starts by generating randomly simulated files and the filenames are stored in an initialization object. The tests are then generated by pytest_generate_tests; file0.txt, file1.txt, etc. Tests are generated from a YAML file which includes in input string like cat %s and a substitution string like file*.txt, which generates 1 test per file it matches in pytest_generate_tests. Thus, I need the files to exist before pytest_generate_tests is called, else files won't be matched.

Before I had encountered the issue, I had an initialization fixture in conftest.py:

@pytest.fixture(scope="session", autouse=True)
def initializer(request):
    # ...do some stuff with the request
    return InitializeTests(...)

class InitializeTests():
    def __init__(self, n):
        # ...generate n files

which I could then use in the file tests_0.py:

test_a(initializer, input_string):
    # ...

and test_a's are generated by:

def pytest_generate_tests(metafunc):
    input_strings = manipulate_the_yaml_file() # This requires the files to exist.
    if "input_string" in metafunc.fixturenames:
        metafunc.parametrize("input_string", input_strings)

I then tried using a global variable to get the initializer and share it across the files as explained in here. I then put the initialization at the top of pytest_generate_tests and calling conftest.initializer from within test_a, but then the initialization step gets run for every test method I add, test_b etc.

So the question is, how can I run a method before pytest_generate_tests and keep the instance of the initialization class across all tests in the session?

Upvotes: 4

Views: 3062

Answers (1)

Gunnar
Gunnar

Reputation: 113

Just writing the problem gave me an obvious solution given the second method using globals:

if "initializer" not in globals():
    initialize()

where initialize creates the global variable initializer and thus only creates it once. However, I don't really like working with globals as I thought fixtures or some other py.test technique could help me, and would gladly hear a better answer.

Upvotes: 2

Related Questions