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

Using fixtures in pytest.mark.parametrize #349

Open
pytestbot opened this issue Aug 30, 2013 · 89 comments
Open

Using fixtures in pytest.mark.parametrize #349

pytestbot opened this issue Aug 30, 2013 · 89 comments

Comments

@pytestbot
Copy link

@pytestbot pytestbot commented Aug 30, 2013

Originally reported by: Florian Rathgeber (BitBucket: frathgeber, GitHub: frathgeber)


I often have a use case like the following contrived example:

@pytest.fixture
def a():
    return 'a'

@pytest.fixture
def b():
    return 'b'

@pytest.mark.parametrize('arg', [a, b])
def test_foo(arg):
    assert len(arg) == 1

This doesn't currently do what's intended i.e. arg inside the test function is not the fixture value but the fixture function.

I can work around it by introducing a "meta fixture", but that's rather ugly:

@pytest.fixture(params=['a', 'b'])
def arg(request, a, b):
    return {'a': a, 'b': b}[request.param]

def test_foo(arg):
    assert len(arg) == 1

It would be convenient if a syntax like in the first case was supported.


@pytestbot

This comment has been minimized.

Copy link
Author

@pytestbot pytestbot commented Jun 21, 2014

Original comment by Matthias Geier (BitBucket: geier, GitHub: geier):


This would be a great feature!

I found another (I don't know if more or less ugly) work-around:

#!python

@pytest.mark.parametrize('arg', ['a', 'b'])
def test_foo(arg, request):
    val = request.getfuncargvalue(arg)
    assert len(val) == 1

This doesn't work, however, with parametrized fixtures.

BTW, it would also be great if fixtures were supported in the params argument of pytest.fixture.

@pytestbot

This comment has been minimized.

Copy link
Author

@pytestbot pytestbot commented Jun 25, 2014

Original comment by Floris Bruynooghe (BitBucket: flub, GitHub: flub):


Tentatively assigning this to me as I think I might be able to come up with a reasonable patch. It'll probably take me a long while though so don't let that discourage anyone else from working on this, assigning it more as a way of not forgetting about it.

@pytestbot

This comment has been minimized.

Copy link
Author

@pytestbot pytestbot commented Aug 3, 2014

Original comment by Praveen Shirali (BitBucket: praveenshirali, GitHub: praveenshirali):


The quoted examples work because functions a and b are part of the same module as test_foo, and within the scope of the example, the parametrization should work even if @pytest.fixture decorator isn't present around functions a and b. They are getting used as regular python functions and not as pytest fixtures. Note that fixtures can also be defined in external modules like conftest.py.

Another alternative to the above example is to directly call these functions in the list.

#!python

@pytest.mark.parametrize('arg', [a(), b()])
def test_foo(arg):
    assert len(arg) == 1
@pytestbot

This comment has been minimized.

Copy link
Author

@pytestbot pytestbot commented Sep 9, 2014

Original comment by BitBucket: dpwrussell, GitHub: dpwrussell:


This would be an awesome feature.

@praveenshirali I don't think your alternative is used as a fixture, it just calls the fixture function. So it would be run repeatedly. You would also have to specify the arguments to the fixture if there were any which could begin the cycle over again if they are also fixtures.

@mgeier

This comment has been minimized.

@jlmenut

This comment has been minimized.

Copy link

@jlmenut jlmenut commented Nov 19, 2015

Yes, I would like very much to have this feature also. Maybe a line in the doc explaining it's not possible for the moment would be useful also.

@kevincox

This comment has been minimized.

Copy link
Contributor

@kevincox kevincox commented Feb 19, 2016

It would also be killer if this supported parameterized fixtures generating the product of the fixtures. Although this might be a little much.

@pytest.fixture(params=["1", " ", 1, True, [None], {1:2}])
def truthy(request):
    return request.param

@pytest.fixture(params=[False, None, "", 0, [], {}])
def falsey(request):
    return request.param

@pytest.mark.parameterize("val,res", [
    (truthy, True),
    (falsey, False),
])
def test_bool(val, res)
    assert bool(val) is res
@SUNx2YCH

This comment has been minimized.

Copy link

@SUNx2YCH SUNx2YCH commented Feb 26, 2016

+1 for this feature.
BTW, combining Florian Rathgeber and Matthias Geier solutions we can get a bit nicer "meta fixture":

@pytest.fixture
def a():
    return 'a'

@pytest.fixture
def b():
    return 'b'

@pytest.fixture(params=['a', 'b'])
def arg(request):
    return request.getfuncargvalue(request.param)

def test_foo(arg):
    assert len(arg) == 1
@rabbbit

This comment has been minimized.

Copy link

@rabbbit rabbbit commented Jul 4, 2016

+1 on this.

I'm currently writing tests that look like:

@pytest.fixture
def my_fixture():
      return 'something'

@pytest.fixture
def another_fixture(my_fixture):
      return {'my_key': my_fixture}

def yet_another_fixture():
     return {'my_key': None}

@pytest.mark.parametrize('arg1, arg2', [
    (5, another_fixture(my_fixture())),
    (5, yet_another_fixture()),
)
def my_test(arg1, arg2):
    assert function_under_test(arg2) == arg1

and that's rather ugly.

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jul 5, 2016

@rabbbit your example is structurally wrong and runs fixture code at test importation time

@rabbbit

This comment has been minimized.

Copy link

@rabbbit rabbbit commented Jul 5, 2016

@RonnyPfannschmidt I know - and that's why I'd like to be able to use fixtures in parametrize? And that would be awesome.

My example is wrong, but it follows the guideline of "always use fixtures". Otherwise we'd end up with fixtures in normal tests, and workarounds in parametrized tests.

Or is there a way of achieving this already, outside of dropping parametrize and doing 'if/elses' in the test function?

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jul 5, 2016

There is a upcoming proposal wrt "merged" fixtures, there is no implementation yet

@nicoddemus

This comment has been minimized.

Copy link
Member

@nicoddemus nicoddemus commented Jul 5, 2016

For reference: #1660

@rabbbit

This comment has been minimized.

Copy link

@rabbbit rabbbit commented Jul 5, 2016

ok, I don't understand python.

If the below works:

@pytest.fixture
def my_fixture
    return 1

def test_me(my_fixture):
    assert 1 == my_fixture

wouldn't the below be simpler? And an exact equivalent?

@pytest.fixture
def my_fixture
    return 1

@pytest.mark.parametrize('fixture', [my_fixture])
def test_me(fixture):
    assert 1 == my_fixture

Am I wrong to think that mark.parametrize could figure out whether an argument is a pytest.fixture or not?

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jul 5, 2016

atm parametrize cannot figure it, and it shouldnt figure it
there will be a new object to declare a parameter will request a fixture/fixture with parameters

some documentation for that is in the features branch

@rabbbit

This comment has been minimized.

Copy link

@rabbbit rabbbit commented Jul 5, 2016

yeah, I read the proposal.

I'm just surprised you're going with pytest.fixture_request(' default_context')it feels very verbose?

after all,

@pytest.fixture
def my_fixture
    return 1

def test_me(my_fixture):
    assert 1 == my_fixture

could also turn to

@pytest.fixture
def my_fixture
    return 1

def test_me(pytest.fixture_request(my_fixture)):
    assert 1 == my_fixture

but that's not the plan, right?

On 5 July 2016 at 16:17, Ronny Pfannschmidt notifications@github.com
wrote:

atm parametrize cannot figure it, and it shouldnt figure it
there will be a new object to declare a parameter will request a
fixture/fixture with parameters

some documentation for that is in the features branch


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#349 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/AARt0kUxVSL1GMeCtU-Kzy3Pg80mW7Ouks5qSmdmgaJpZM4FEMDj
.

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jul 5, 2016

thats not even valid python syntax

the fixture-request would be used as a parameter value to tell py.test "use the value of a fixture you create later on"

there are already parametzw using examples, and its not overly verbose

@kibernick

This comment has been minimized.

Copy link

@kibernick kibernick commented Sep 27, 2016

It would be really convenient to have this functionality, perhaps along the lines of "LazyFixture" in pytest-factoryboy

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Sep 27, 2016

@kibernick we already did put a outline of possible implementations into the documentation

we just need time or a person implementing it

@Brachi

This comment has been minimized.

Copy link

@Brachi Brachi commented Sep 30, 2016

@RonnyPfannschmidt can you link to that part of the documentation you mention? Can't find it.
Edit: nevermind. http://doc.pytest.org/en/latest/proposals/parametrize_with_fixtures.html

@TvoroG

This comment has been minimized.

Copy link

@TvoroG TvoroG commented Oct 2, 2016

@RonnyPfannschmidt, can you please check this out https://github.com/TvoroG/pytest-fixture-mark? Need some feedback

@Brachi

This comment has been minimized.

Copy link

@Brachi Brachi commented Oct 3, 2016

@TvoroG good work.
Currently this seems to be failing. Is it possible to support it as well?

import pytest                                                                  


@pytest.fixture(params=[1, 2, 3])                                              
def one(request):                                                              
    return str(request.param)                                                  


@pytest.fixture                                                                
def two():                                                                     
    return 4                                                                   


@pytest.fixture(params=[                                                       
    pytest.mark.fixture('one'),                                                
    pytest.mark.fixture('two')                                                 
])                                                                             
def some(request):                                                             
    return request.param                                                       


def test_func(some):                                                           
    assert some in {'1', '2', '3', 4}
@TvoroG

This comment has been minimized.

Copy link

@TvoroG TvoroG commented Oct 4, 2016

@Brachi, thanks for catching it! It works now, but more nested structures need some dependency sorting to instantiate fixtures in correct order. I'll update the plugin code when i'm done.

@TvoroG

This comment has been minimized.

Copy link

@TvoroG TvoroG commented Oct 4, 2016

@Brachi, I fixed it. Let me know if there is more such cases when plugin is failing

@Brachi

This comment has been minimized.

Copy link

@Brachi Brachi commented Oct 4, 2016

@TvoroG great, thanks for the quick reply. I tested it a little more and here's another contrived example that doesn't work, based on a real use case (where one actually returns an object)

import pytest


@pytest.fixture(params=[1, 2, 3])
def one(request):
    return request.param


@pytest.fixture(params=[pytest.mark.fixture('one')])
def as_str(request):
    return str(request.getfixturevalue('one'))


@pytest.fixture(params=[pytest.mark.fixture('one')])
def as_hex(request):
    return hex(request.getfixturevalue('one'))


def test_as_str(as_str):
    assert as_str in {'1', '2', '3'}


def test_as_hex(as_hex):
    assert as_hex in {'0x1', '0x2', '0x3'}


# fails at setup time, with ValueError: duplicate 'one'
def test_as_hex_vs_as_str(as_str, as_hex):
    assert int(as_hex, 16) == int(as_str)
@nicoddemus

This comment has been minimized.

Copy link
Member

@nicoddemus nicoddemus commented Oct 4, 2016

@TvoroG, pytest-fixture-mark seems very nice! I hope I get the chance to try it soon! 😄

Perhaps discussion specific to it should be moved to https://github.com/TvoroG/pytest-fixture-mark thought? 😉

@dmtucker

This comment has been minimized.

Copy link

@dmtucker dmtucker commented Jan 18, 2019

Something like this?

import pytest

@pytest.fixture
def fixture1():
    return 1

@pytest.fixture
def fixture2():
    return 2

@pytest.fixture
def x(request):
    return request.getfixturevalue(request.param)

@pytest.mark.parametrize('x', ['fixture1', 'fixture2'], indirect=['x'])
def test_indirect(x):
    assert 0 < x < 3
@brunoais

This comment has been minimized.

Copy link

@brunoais brunoais commented Jan 18, 2019

From what I understood, there's more missing when parameterization is needed....
From your code, I can make an untested version.

import pytest

@pytest.fixture
def fixture1(request):
    return request.param * 2

@pytest.fixture
def fixture2(request):
    return request.param * 4

@pytest.fixture
def x(request):
    return request.getfixturevalue(request.param)

@pytest.mark.parametrize('x,fixture1,fixture2', [('fixture1',1,0), ('fixture2',0,4)], indirect=['x','fixture1','fixture2'])
def test_indirect(x):
    assert 0 < x < 5

Thank you dmtucker for starting this.

@dmtucker

This comment has been minimized.

Copy link

@dmtucker dmtucker commented Jan 18, 2019

Eh, looks like that doesn't quite work...

In test_indirect: function uses no fixture 'fixture1'

I thought this could be acheived by parametrizing the fixtures themselves, but that doesn't appear to work either:

import pytest

@pytest.fixture(params=[1, 0])
def fixture1(request):
    return request.param * 2

@pytest.fixture(params=[0, 4])
def fixture2(request):
    return request.param * 4

@pytest.fixture
def x(request):
    return request.getfixturevalue(request.param)

@pytest.mark.parametrize('x', ['fixture1', 'fixture2'], indirect=['x'])
def test_indirect(x):
    assert 0 < x < 5
================================================= ERRORS =================================================
_______________________________ ERROR at setup of test_indirect[fixture1] ________________________________
The requested fixture has no parameter defined for test:
    test_indirect3.py::test_indirect[fixture1]

Requested fixture 'fixture1' defined in:
test_indirect3.py:4

Requested here:
test_indirect3.py:13
_______________________________ ERROR at setup of test_indirect[fixture2] ________________________________
The requested fixture has no parameter defined for test:
    test_indirect3.py::test_indirect[fixture2]

Requested fixture 'fixture2' defined in:
test_indirect3.py:8

Requested here:
test_indirect3.py:13
======================================== short test summary info =========================================
ERROR test_indirect3.py::test_indirect[fixture1]
ERROR test_indirect3.py::test_indirect[fixture2]
======================================== 2 error in 0.10 seconds =========================================
@brunoais

This comment has been minimized.

Copy link

@brunoais brunoais commented Jan 18, 2019

Does it work like this? (changed first param of parametrize)

import pytest

@pytest.fixture
def fixture1(request):
    return request.param * 2

@pytest.fixture
def fixture2(request):
    return request.param * 4

@pytest.fixture
def x(request):
    return request.getfixturevalue(request.param)

@pytest.mark.parametrize('x', [('fixture1',1,0), ('fixture2',0,4)], indirect=['x','fixture1','fixture2'])
def test_indirect(x):
    assert 0 < x < 5
@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jan 18, 2019

@brunoais i believe both attribute names need to be put in the argument name list, and only the values need to be in the parameter list

@CAM-Gerlach

This comment has been minimized.

Copy link

@CAM-Gerlach CAM-Gerlach commented Jan 24, 2019

@RonnyPfannschmidt This is the most-commented open issue on the Pytest Github, and the second-most commented of any issue, open or closed (and that by a narrow margin), yet there appears to be no serious effort to implemented a proper solution aside from ugly, unofficial, user-created workarounds involving multiple layers of other fixtures, or simply not using fixtures for such altogether.

Obviously, the dev team has limited resources, but given dozens of other PRs are getting merged every month, is there a reason addressing this still isn't a priority for pytest? Is this not seen as a valid use case for fixtures and/or pytest.parameterize?

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jan 24, 2019

@CAM-Gerlach its a valid use-case, but not a priority for me personally - there is various really nasty details in the fixture system that will take a while to correctly figure (like for example covariant parameterize), layering of dependencies and other issues before we can hope to make more than a implementation that will simply break down once a requested fixture is parameterized

its not like we don't want this to happen, but with our personal and mental resources we have to be realistic - if we cant hope to make it work well enough we don't start, what we put into pytest should beat the external plugins/workaroudns by a order of magnitude - we currently cant do that so the workarounds are already enough

personally id rather do this never than just pulling a nasty incomplete workaround into pytest we will then regret for the next 5-10 years

@carver

This comment has been minimized.

Copy link

@carver carver commented Jan 24, 2019

There are a bunch of different proposed workarounds in the thread. Many of them have bugs, or follow-up comments that are hard for people to quickly compile into a single working example.

Maybe someone on the team could do a writeup in the docs with a "blessed" workaround (and mention some limitations of the approach, like you did here).

❤️ for all your work

@RonnyPfannschmidt

This comment has been minimized.

Copy link
Member

@RonnyPfannschmidt RonnyPfannschmidt commented Jan 24, 2019

personally i consider https://pypi.org/project/pytest-lazy-fixture/ a valid workaround (with the caveat that it currently doesn't handle parameterization - its also closest to what we consider pulling into core

my personal plan to drive it forward is to enable the pytest internals to provide whats needed to enable parameterize support in that, and from there expanding towards working on a inclusion

@Corleo

This comment has been minimized.

Copy link

@Corleo Corleo commented Mar 11, 2019

I can use fixtures as arguments in parametrize using the getfixture fixture that returns a function that calls another fixture:

import pytest

@pytest.fixture
def a():
    return 'a123'

@pytest.fixture
def b():
    return 'b321'

@pytest.fixture
def getfixture(request):
    def _getfixture(name):
        return request.getfixturevalue(name)
    return _getfixture

@pytest.mark.parametrize(
    '_fixture, expect', [
        pytest.param('a', 'a123'),
        pytest.param('b', 'b321'),
    ]
)
def test_foo(getfixture, _fixture, expected):
    assert getfixture(_fixture) == expected
@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Mar 28, 2019

My two cents: it seems to me that there are two core concepts around fixtures and parametrization that people want from pytest. This post refers to the second but it is good to look at both for consistency of the architecture.

feature 1: cartesian product of parametrized fixtures each test is run for each combination of parameters present in the set of fixtures it relies upon. Note: the @pytest.mark.parametrize on the test function itself can be considered "just" dummy function-scoped fixtures here ; actually in another post we suggested to entirely implement the concept of test function parameters by function-scope fixture, so as to simplify things to a single concept: "(parametrized) fixture".

Feature 1 is today correctly provided by pytest, and in pytest-cases we even proposed a way to transform all parameter marks into fixtures, so as to begin the transition to this simpler system.

Feature 2: aggregation/union of parametrized fixtures this is what this post seems to be about: the possibility to combine two or more fixtures into a single one, by union of all their instantiated (parametrized) values. This is what I have started to provide in pytest-cases with @cases_data but it is focused on sourcing parameter values from several parameter functions, not to union fixture values from several fixtures. I think that it is still useful, but it does not answer the main need from this post. I'll have a look today, to see if I can provide a workaround.

Edit: I'm wondering if the second feature is actually a superset of the OP's... I might have been mistaken here. Anyway I'll continue to work on it to see if it makes sense.

Edit 2 have a look here it brings some funny cases for fixture unions + parameters on the table... ideas more than welcome to find the "correct desired" behaviour to implement. (@RonnyPfannschmidt @nicoddemus ?)

@toonarmycaptain

This comment has been minimized.

Copy link

@toonarmycaptain toonarmycaptain commented Apr 1, 2019

My use case (please point it out if I'm off topic) is:

@pytest.fixture()
def test_my_custom_class():
test_name = 'Arthur, King of the Britons'
yield my_custom_class(test_name)

@pytest.mark.parametrize(
'argument, result',
[test_my_custom_class, 'some evaluated value',
'not my custom class', 'something else',
])

def test_my_class(self, argument, result):
    assert some_func(argument) == result

Is this what's so hard to figure out because of fixture/parametrize decorator magic, or is there a simple alternative to what I want to do, which is simply use a fixture (or preferably several different fixtures for different testing cases) returning an example of my class as a parameter to a test.

@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Apr 2, 2019

From what @RonnyPfannschmidt explained, the issue is to control what happens in case of parametrization. This case basically is a specific case of "fixture unions" where a fixture (here your parameter) depends on the union of some other fixtures. In your example: what happens when test_my_custom_class has a parameter ? Would 'some evaluated value' be the expected outcome for each parameterized value ? And of course all the ids generation is impacted too, if you do not provide an explicit ids list.

If you do not need parametrization, then as suggested above the pytest-lazy-fixture plugin should solve your problem, from what I understand (I did not test though)

@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Apr 3, 2019

For those of you who wish to try, there is now a draft implementation of fixture union available in pytest-cases 1.6.0. It matches the scope request for proposal, so you'll have to wait a bit more for the support inside pytest.mark.parametrize. But that will be quite easy now that the callspec engine is modified (in this draft) to accept both unions and cartesian products.

@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Jun 13, 2019

Update on this topic: this feature is now available in the new release of pytest-cases.

It can handle ridiculously complex cases where several references are used from several places. See for example this test.

The principle of the solution to handle union fixtures (and therefore fixture references in parameters) was to replace the concept of "fixture closure" (=set of all fixtures required at a node) with a "fixture closure tree". In other words, to describe all the alternate branches and their (different) local closures. It has been tested on a couple of nasty examples such as this one.

Please play with it if you're interested, and if the global behaviour seems appropriate I believe that it could constitute a solid foundation for a PR, replacing the getfixtureclosure and parametrize functions. Note that it would really help that parameters be considered as "private-scoped" fixtures, rather than being "discarded arg names" (the new ignore_args input to getfixtureclosure that appeared in 4.6+).

EDIT: WARNING installing pytest-cases now has effects on the order of tests execution, even if you do not use its features. One positive side effect is that it fixed #5054 . But if you see less desirable ordering (in particular with session-scope, module-scope etc.) could please be kind enough to report it (on the project page directly).

@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Jun 14, 2019

Quick update: I just pushed a 1.8.0 of pytest-cases. The main difference is that there is now by default an explicit style for the ids corresponding to alternatives in a union. Alternate styles are also proposed, see fixture_union API doc.

@slavaatsig

This comment has been minimized.

Copy link

@slavaatsig slavaatsig commented Dec 17, 2019

Any thought about the lazy load approach from here https://github.com/ionelmc/python-lazy-object-proxy
Worked flawlessly for me in parametrize for fixture that needed to messup with database.

@last-partizan

This comment has been minimized.

Copy link

@last-partizan last-partizan commented Dec 17, 2019

@smarie Thank you for pytest-cases, i've managed to get what i wanted, and it looks almost fine, except for fixture names :)

import pytest
from pytest_lambda import lambda_fixture
from pytest_cases import fixture_ref, pytest_parametrize_plus

from . import models


def lazy_fixture_generator(mod):
    """
    Lazy = lazy_fixture_generator(globals())
    """
    ids = (x for x in range(1000))

    def Lazy(fun):
        """
        Lazy fixture loading from lambda

        Usage:
        @pytest_parametrize_plus("args", [Lazy(lambda f1, f2: (f1.atrr, f2.attr))])
        """
        name = f"lazy{next(ids)}"
        mod[name] = lambda_fixture(fun)
        return fixture_ref(name)
    return Lazy


Lazy = lazy_fixture_generator(globals())


@pytest.fixture
def book1():
    return models.Book(name="Moby Dick")


@pytest.fixture
def book2():
    return models.Book(name="Alice in Wonderland")


@pytest_parametrize_plus("name, expects", [
    (Lazy(lambda book1: book1.name), "Moby Dick"),
    (Lazy(lambda book2: book2.name), "Alice in Wonderland"),
])
@pytest.mark.django_db
def test_get_or_create_book(name, expects):
    book = models.Book.objects.get_or_create(name=name)[0]
    assert book.name == expects
test output
 pipenv run pytest -vv --disable-warnings
Test session starts (platform: linux, Python 3.8.0, pytest 4.5.0, pytest-sugar 0.9.2)
cachedir: .pytest_cache
Django settings: bookstore.settings (from ini file)
rootdir: /home/serg/work/git/example/src/bookstore, inifile: pytest.ini
plugins: django-3.7.0, sugar-0.9.2, lambda-1.1.0, cases-1.11.9
collecting ... 
 core/tests.py::test_get_or_create_book[test_get_or_create_book_name_expects_is_fixtureproduct__0] ✓50% █████     
 core/tests.py::test_get_or_create_book[test_get_or_create_book_name_expects_is_fixtureproduct__1] ✓100% ██████████

Results (0.45s):
       2 passed
@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Dec 18, 2019

@last-partizan I opened an issue concerning your comment in pytest-cases: smarie/python-pytest-cases#69

Feel free to discuss it there

@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Dec 19, 2019

For information thanks to @last-partizan pytest-cases 1.12.0 has much more readable test ids when a fixture_ref() is used inside a @pytest_parametrize_plus (and therefore when fixture unions are created behind the scenes). Feel free to test it !

Note: when we'll collectively feel that this reference implementation is mature enough, it will probably be time to try to migrate it to pytest core. Indeed manipulation of the fixture closures is something too low-level to stay in a plugin for ever : sooner or later it will break. Somethink to think about for 2020 ? :)

@andreabisello

This comment has been minimized.

Copy link

@andreabisello andreabisello commented Dec 24, 2019

sorry i'm not able to understand.
can i @parametrize test reading data from a fixture?
i would like to read an array of data from a json with a fixture and then parametrize a test in order to generate a test for every element of the list, but it looks like i cannot use a fixture as argsvalues of https://docs.pytest.org/en/latest/reference.html#pytest-mark-parametrize-ref
thanks sorry if i'm off topic.

@smarie

This comment has been minimized.

Copy link

@smarie smarie commented Jan 16, 2020

@andreabisello , please check first this post : https://stackoverflow.com/questions/42228895/how-to-parametrize-a-pytest-fixture/56871701#56871701

It clarifies the role and responsibilities of fixtures and parameters.

Then fixture_ref can be used if you wish to "reuse" a (parametrized or not) fixture in a list of parameters. Nothing "more", really.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
You can’t perform that action at this time.