Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use multiple yield statements as an alternative for parametrization #1595

Closed
nicoddemus opened this issue Jun 7, 2016 · 6 comments
Closed
Labels
topic: parametrize related to @pytest.mark.parametrize type: proposal proposal for a new feature, often to gather opinions or design the API around the new feature

Comments

@nicoddemus
Copy link
Member

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.

@nicoddemus nicoddemus added type: proposal proposal for a new feature, often to gather opinions or design the API around the new feature topic: parametrize related to @pytest.mark.parametrize labels Jun 7, 2016
@RonnyPfannschmidt
Copy link
Member

I'm strictly opposed, that model is broken

See #16 for the same issue in a different context

@nicoddemus
Copy link
Member Author

I read #16, thanks.

I'm not sure what you mean by "that model is broken", but looking at a UX point of view parametrizing fixtures using yield statements like the one I posted looks very good to me. But of course I understand it might not be simple (or even impossible) to implement in the current design (that's why I put that disclaimer at the end).

@RonnyPfannschmidt
Copy link
Member

it is technically impossible to manage setupstate in a consistent way if you merge parameterization and value creation because you need to paramerize at collect time

@nicoddemus
Copy link
Member Author

Yep, that's what I figured, we have to obtain all items during the collection phase, and fixtures parametrized that way won't be executed until the first test that uses it executes, long past the collection phase. 😞

Well, let's close this then! 😁

@jpic
Copy link

jpic commented Dec 15, 2017

If you want a silly question: why is it that we can't add a test after setup time ? in case tests are distributed perhaps ?

@RonnyPfannschmidt
Copy link
Member

@jpic in the current model of pytest, there is a collect phase, where all tests are collected,and afterwards the number of tests no longer changes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: parametrize related to @pytest.mark.parametrize type: proposal proposal for a new feature, often to gather opinions or design the API around the new feature
Projects
None yet
Development

No branches or pull requests

3 participants