-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Comments
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 |
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. |
Original comment by Praveen Shirali (BitBucket: praveenshirali, GitHub: praveenshirali): The quoted examples work because functions Another alternative to the above example is to directly call these functions in the list.
|
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. |
Here's a related stackoverflow question: http://stackoverflow.com/questions/24340681/how-to-concatenate-several-parametrized-fixtures-into-a-new-fixture-in-py-test |
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. |
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 |
+1 for this feature. @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 |
+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. |
@rabbbit your example is structurally wrong and runs fixture code at test importation time |
@RonnyPfannschmidt I know - and that's why I'd like to be able to use fixtures in 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? |
There is a upcoming proposal wrt "merged" fixtures, there is no implementation yet |
For reference: #1660 |
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?
Am I wrong to think that |
atm parametrize cannot figure it, and it shouldnt figure it some documentation for that is in the features branch |
yeah, I read the proposal. I'm just surprised you're going with 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
|
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 |
It would be really convenient to have this functionality, perhaps along the lines of "LazyFixture" in pytest-factoryboy |
@kibernick we already did put a outline of possible implementations into the documentation we just need time or a person implementing it |
@RonnyPfannschmidt can you link to that part of the documentation you mention? Can't find it. |
@RonnyPfannschmidt, can you please check this out https://github.com/TvoroG/pytest-fixture-mark? Need some feedback |
@TvoroG good work.
|
@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. |
@Brachi, I fixed it. Let me know if there is more such cases when plugin is failing |
@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
|
@TvoroG, Perhaps discussion specific to it should be moved to https://github.com/TvoroG/pytest-fixture-mark thought? 😉 |
Usually I have a file with unittest assertions, so I mix it with pytest when I need it. django_assertions.py from django.test import TestCase
_dj_testcase = TestCase()
dj_sub_test = _dj_testcase.subTest test_serializers.py from django_assertions import dj_sub_test
@pytest.fixture
def attendance():
attendance = baker.make('Attendance', _fill_optional=True)
baker.make('AttendanceFile', attendance=attendance)
return attendance
@pytest.mark.django_db
def test_values(attendance):
serializer = AttendanceSerializer(attendance)
values = (
('id', attendance.pk),
('customer_name', attendance.customer_name),
('document_id', attendance.document_id),
('status', attendance.status),
('status_label', AttendanceStatus(attendance.status).label),
('resume', attendance.resume),
)
for attr, value in values:
with dj_sub_test():
assert serializer.data[attr] == value |
Solved my task by using first (out of two) methods described here: https://miguendes.me/how-to-use-fixtures-as-arguments-in-pytestmarkparametrize |
@remort , this works as long as your fixtures are not parametrized, otherwise you'll need pytest-cases as shown in this example: from pytest_cases import fixture, parametrize
@fixture
@parametrize(a=[0, 1])
def my_fix(a):
return f"my_fix_{a}"
@parametrize(b=["hello", my_fix])
def test_foo(b):
print(b) leading to
(note that I used the alternative kwargs syntax above but you can also use the pytest.mark.parametrize syntax if you prefer) |
For another concrete example, I'm currently working on a PR where I am trying to write a single test (suite) to run against several different backends. What I would like to be able to write is something like this:
I'm currently working around it by using Unless there's currently a better way to do this. |
Pytest-lazy-fixtures is a external plugin to do part of that |
And pytest-cases works too @waynew :) See #349 (comment) and doc reference https://smarie.github.io/python-pytest-cases/pytest_goodies/#parametrize EDIT: simply replace |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
Just a quick note to say the |
@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) 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. |
Originally reported by: Florian Rathgeber (BitBucket: frathgeber, GitHub: frathgeber)
I often have a use case like the following contrived example:
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:
It would be convenient if a syntax like in the first case was supported.
The text was updated successfully, but these errors were encountered: