Vincent
Vincent

Reputation: 31

Parametrize Pytest test with list returned from fixture

I have a test that iterates over a list of dictionaries (parsed from a csv file in S3) returned from a fixture and performs assertions.

In pseudocode:

# s_3 is a fixture
def my_fixture(s_3):
  s_3.get_data_from_s3()
  yield s_3_data_as_list_of_dicts

def my_test(my_fixture):
  for entry in my_fixture:
    do my assertions

I also had this written where I passed in the output into @pytest.mark.parametrize, but it wasn't from a fixture, but rather from just a method where I had to instantiate/connect S3.

I want to be able to leverage my fixtures to get the data and parametrize the test based on the output, as in:

# s_3 is a fixture
def my_fixture(s_3):
  s_3.get_data_from_s3()
  yield s_3_data_as_list_of_dicts

@pytest.mark.parametrize("entries", [output from my_fixture])
def my_test(entries):
    do my assertions

I have seen things along these lines, but nothing that was able to help be resolve this issue - if there is a resolution other than just using a non-fixture method.

Upvotes: 0

Views: 1780

Answers (1)

Guy
Guy

Reputation: 50854

You can use yield instead of return in my_fixture

@pytest.fixture
def my_fixture(s_3):
    s_3.get_data_from_s3()
    yield s_3_data_as_list_of_dicts


def my_test(my_fixture):
    print(my_fixture) # my_fixture is a list of dicts

Edit:

@pytest.mark.parametrize is executed in collection time, when pytest is collecting all the tests that need to run. @pytest.fixture is executed in execution time, when the current test/module/session (depends on scope) is running.

If you would like each dictionary as a parameter to the test you can build non-fixture function and send it as a parameter to parametrize

def data_source():
    for d in s_3_data_as_list_of_dicts:
        yield d


@pytest.mark.parametrize('d', data_source())
def test_my_test(d):
    print(d) # d is a single dict

Upvotes: 2

Related Questions