Skip to content

Use multiple yield statements as an alternative for parametrization #1595

@nicoddemus

Description

@nicoddemus

After we merge #1586, I think we can discuss using yield as an alternative for fixture parametrization.

As mentioned at the end of yield_fixture.html:

  • usually yield is used for producing multiple values.
    But fixture functions can only yield exactly one value.
    Yielding a second fixture value will get you an error.
    It's possible we can evolve pytest to allow for producing
    multiple values as an alternative to current parametrization.
    For now, you can just use the normal
    :ref:fixture parametrization <fixture-parametrize>
    mechanisms together with yield-style fixtures.

I really like this idea, it seems to fix really nicely on how I've parametrized fixtures in the past. Consider:

import pytest


@pytest.fixture(params=['zip', 'tar'])
def archive_impl(request, tmpdir):
    if request.param == 'zip':
        import zipfile
        with zipfile.open(tmpdir.join('file.zip'), 'w') as f:
            yield f

    elif request.param == 'tar':
        import tarfile
        with tarfile.open(tmpdir.join('file.tar'), 'w') as f:
            yield f


def test_archiver(archive_impl):
    # ...

If we can use multiple yield statements, this becomes:

import pytest


@pytest.fixture
def archive_impl(tmpdir):    
    import zipfile
    with zipfile.open(tmpdir.join('file.zip'), 'w') as f:
        yield f

    import tarfile
    with tarfile.open(tmpdir.join('file.tar'), 'w') as f:
        yield f


def test_archiver(archive_impl):
    # ...

I find the above much easier to understand, and it is perfectly backward compatible since multiple yields are currently disallowed.

Having said that I'm not sure how easy it would be to actually implement this, since parametrization currently occurs during the collection phase, while fixtures yielding values would only be noticed during the setup phase.

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: parametrizerelated to @pytest.mark.parametrizetype: proposalproposal for a new feature, often to gather opinions or design the API around the new feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions