Repository navigation
Open
Labels
topic: parametrizerelated to @pytest.mark.parametrizerelated to @pytest.mark.parametrizetype: proposalproposal for a new feature, often to gather opinions or design the API around the new featureproposal for a new feature, often to gather opinions or design the API around the new feature
Description
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) == 1This 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) == 1It would be convenient if a syntax like in the first case was supported.
Reacted by Laurent Senta, Cory Dodt, AA, Michael K., Jāzeps Baško, Dmitry Misharov, Raphael Das Gupta, Darius Lapūnas, Eugene Pokidov, Darlin Alberto and 571 more
Reacted by Dmitriy Kunitskiy, Kazantcev Andrey, Anja Pilz, Michael Wojnowicz, Vitalii Paprotskyi, online-python, zukias-ai, Elizaveta Dokshina, Dominic Frei, Alex LordThorsen and 4 more
Reacted by Janusz Skonieczny, 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко), Pavel, Dmitriy Kunitskiy, Nikita Shupeyko, Kazantcev Andrey, Michael Wojnowicz, Vitalii Paprotskyi, online-python, Danny Goldstein and 11 more
Reacted by Z, antonio_antuan, Robsdedude, Adam Suban-Loewen, Janusz Skonieczny, Miro Hrončok, jonathan MERCIER, Remy Gwaramadze, 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко), Ilia Kurenkov and 46 more
Reacted by Vitalii Paprotskyi, online-python, Thales Maciel, zukias-ai, Elizaveta Dokshina, Matthew Gamble, Lev Zaplatin, Arcady Usov, Dominic Frei, Alex LordThorsen and 6 more
Reacted by Никита Конин, Elizaveta Dokshina, Changsheng Wu, Dominic Frei, Alex LordThorsen, John, João Victor Davim, Renato Damas, Roc, Ashwin Balamohan and 4 more
Metadata
Metadata
Assignees
Labels
topic: parametrizerelated to @pytest.mark.parametrizerelated to @pytest.mark.parametrizetype: proposalproposal for a new feature, often to gather opinions or design the API around the new featureproposal for a new feature, often to gather opinions or design the API around the new feature
Activity
pytestbot commentedon 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:
This doesn't work, however, with parametrized fixtures.
BTW, it would also be great if fixtures were supported in the
paramsargument ofpytest.fixture.pytestbot commentedon 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 commentedon Aug 3, 2014
Original comment by Praveen Shirali (BitBucket: praveenshirali, GitHub: praveenshirali):
The quoted examples work because functions
aandbare part of the same module astest_foo, and within the scope of the example, the parametrization should work even if@pytest.fixturedecorator isn't present around functionsaandb. They are getting used as regular python functions and not as pytest fixtures. Note that fixtures can also be defined in external modules likeconftest.py.Another alternative to the above example is to directly call these functions in the list.
pytestbot commentedon 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 commentedon Jun 16, 2015
Here's a related stackoverflow question: http://stackoverflow.com/questions/24340681/how-to-concatenate-several-parametrized-fixtures-into-a-new-fixture-in-py-test
jlmenut commentedon 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 commentedon 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.
SUNx2YCH commentedon Feb 26, 2016
+1 for this feature.
BTW, combining Florian Rathgeber and Matthias Geier solutions we can get a bit nicer "meta fixture":
rabbbit commentedon Jul 4, 2016
+1 on this.
I'm currently writing tests that look like:
and that's rather ugly.
RonnyPfannschmidt commentedon Jul 5, 2016
@rabbbit your example is structurally wrong and runs fixture code at test importation time
rabbbit commentedon 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 commentedon Jul 5, 2016
There is a upcoming proposal wrt "merged" fixtures, there is no implementation yet
nicoddemus commentedon Jul 5, 2016
For reference: #1660
107 remaining items
RonnyPfannschmidt commentedon Aug 8, 2022
Lewiscowles1986 commentedon Aug 8, 2022
chrisk314 commentedon Apr 19, 2024
Just a quick note to say the
pytest-lazy-fixturepackage mentioned as a workaround here appears to be dead, with many unaddressed open issues and it's not compatible withpytest>=8.0.0. This would be a nice quality of life feature to have natively inpytest.smarie commentedon Jul 12, 2024
@chrisk314 You can use pytest-cases as a workaround (https://smarie.github.io/python-pytest-cases), it is alive and kicking :) (and compliant with pytest 8 since version 3.8.3)
See #349 (comment)
Still, I agree with you that it would be better to refactor the internal engine to handle all of this in pytest. This would require massive rework unfortunately... which is why the team did not do it yet.
MRGuziX commentedon Mar 26, 2025
Any news on that? That would be and great feature... and installing more and more libs to handle those kind of cases it is not the best answer :)
The-Compiler commentedon Mar 26, 2025
If there were any news, it would be here in the issue. That's kind of the whole point of a public issue tracker.
thetic commentedon Mar 28, 2025
https://github.com/dev-petrov/pytest-lazy-fixtures
kielpins commentedon Apr 1, 2025
MRGuziX commentedon Apr 1, 2025
That cannot be the "only answer" to the problem...
TBH if there is an issue that is open for 12+years I feel like there is no hope for it and it will never be implemented due to beeing in some kind of "backlog hell". Last time there was some bump here it was 9 months ago, and having that would resolve huge amount of "edge" cases in testing.
If I am wrong, deep down it would be nice to be..., and there is a chance for introducing that keep it alive. If there is no option for that "because of reasons" it should be closed with proper comment.
hpk42 commentedon Apr 3, 2025
RonnyPfannschmidt commentedon Apr 3, 2025
implementation is really tricky actually - external implementation currently break down the moment one of the fixtures we depend on is actually parameterized
parameterize would have to act like a fixpoint function to resolve that - and currently most of the internals don't support that
so right now are unable to internally express whats needed for correct resolution
smarie commentedon May 9, 2025
I confirm that ! I had to hack quite a lot to make it work nicely in all situations in a plugin (in pytest-cases). Some of the reasons disclosing the complexity behind this simple need are illustrated here : https://smarie.github.io/python-pytest-cases/unions_theory/
The problem is that a fixture is valid for an entire function scope, while a parameter is one item in the callspec of that function. So I had to "cheat" by creating a new mechanism named "fixture union" to have a fixture only used for some items of the callspec (the parameters that you want). But that "cheating" was quite hard to get right, I had to replace the whole fixture closure by a tree behaving like a list when it is looked at by pytest ; and I had afterthoughts a few months/years after, about other ways to do this (smarie/python-pytest-cases#170 (comment) )
I had to create hundreds of corner/edge-case tests to be sure to cover all situations... so far it seems to have worked pretty well as it has been used for many years with a very limited number of issues, all fixed quickly - but it is clearly not as durable/maintainable in time as it would if the feature was part of pytest. I myself now have a hard time to understand my own ugly hacky code :D . And we do not have that many contributors in pytest-cases - just a few have contributed (huge thanks to them !)
Fix certbot tests after updating pytest to 9.0.2 (#10545)