Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically create pytest fixtures

Tags:

python

pytest

I have a directory full of data files to feed into tests, and I load them using something along the lines of

@pytest.fixture(scope="function")
def test_image_one():
     return load_image("test_image_one.png")

As the test suite grows, this is becoming unmaintainable. Is there a way to programatically create fixtures? Ideally it would be something like:

for fname in ["test_image_one", "test_image_two", ...]:
    def pytest_fixutre_function():
        return load_image("{}.png".format(fname))
    pytest.magic_create_fixture_function(fname, pytest_fixutre_function)

Is there a way to accomplish this?

like image 580
Charles L. Avatar asked Oct 24 '18 22:10

Charles L.


2 Answers

Write a fixture that reads the image file and returns file contents and use indirect parametrization to invoke it. Example:

import pathlib
import pytest


files = [p for p in pathlib.Path('images').iterdir() if p.is_file()]


@pytest.fixture
def image(request):
    path = request.param
    with path.open('rb') as fileobj:
        yield fileobj.read()


@pytest.mark.parametrize('image', files, indirect=True, ids=str)
def test_with_file_contents(image):
    assert image is not None

The test run will yield:

test_spam.py::test_with_file_contents[images/spam.png] PASSED
test_spam.py::test_with_file_contents[images/eggs.png] PASSED
test_spam.py::test_with_file_contents[images/bacon.png] PASSED
like image 97
hoefling Avatar answered Oct 17 '22 09:10

hoefling


Something like this:

@pytest.mark.parametrize('pic', ['f1', 'f2', 'f3'])
def test_pics(pic):
    load_image(pic)

See the docs for details https://docs.pytest.org/en/latest/parametrize.html

like image 1
Jonah Avatar answered Oct 17 '22 10:10

Jonah