Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pytest: running tests multiple times with different input data

Tags:

python

pytest

I want to run through a collection of test functions with different fixtures for each run. Generally, the solutions suggested on Stack Overflow, documentation and in blog posts fall under two categories. One is by parametrizing the fixture:

@pytest.fixture(params=list_of_cases)
def some_case(request):
    return request.param

The other is by calling metafunc.parametrize in order to generate multiple tests:

def pytest_generate_tests(metafunc):
    metafunc.parametrize('some_case', list_of_cases)

The problem with both approaches is the order in which the cases are run. Basically it runs each test function with each parameter, instead of going through all test functions for a given parameter and then continuing with the next parameter. This is a problem when some of my fixtures are comparatively expensive database calls.

To illustrate this, assume that dataframe_x is another fixture that belongs to case_x. Pytest does this

test_01(dataframe_1)
test_01(dataframe_2)
...
test_50(dataframe_1)
test_50(dataframe_2)

instead of

test_01(dataframe_1)
...
test_50(dataframe_1)

test_01(dataframe_2)
...
test_50(dataframe_2)

The result is that I will fetch each dataset from the DB 50 times instead of just once. Since I can only define the fixture scope as 'session', 'module' or 'function', I couldn't figure out how to group my tests to that they are run together in chunks.

Is there a way to structure my tests so that I can run through all my test functions in sequence for each dataset?

like image 392
instant Avatar asked Jan 24 '17 14:01

instant


People also ask

How do you run the same test multiple times in pytest?

Repeating a test If you want to override default tests executions order, you can use --repeat-scope command line option with one of the next values: session , module , class or function (default). It behaves like a scope of the pytest fixture.

Does pytest use multiprocessing?

pytest-mp is a minimalist approach to distributing and segregating pytest tests across processes using python's multiprocessing library and is heavily inspired by pytest-concurrent and pytest-xdist.

Is pytest multithreaded?

This plugin makes it possible to run tests quickly using multiprocessing (parallelism) and multithreading (concurrency).


1 Answers

If you only want to load the dataframes once you could use the scope parameter with 'module' or 'session'.

@pytest.fixture(scope="module", params=[1, 2])
def dataframe(request):
    if request.param == 1:
        return #load datagrame_1
    if request.param == 2:
        return #load datagrame_2

The tests will still be run alternately but the dataframe will only be loaded once per module or session.

like image 56
Cedric Avatar answered Oct 21 '22 22:10

Cedric