I want to be able to return a value from a fixture to multiple tests/test classes, but the value that gets passed is a function.
Here's my code:
import pytest
@pytest.fixture()
def user_setup():
user = {
'name': 'chad',
'id': 1
}
return user
@pytest.mark.usefixtures('user_setup')
class TestThings:
def test_user(self):
assert user_setup['name'] == 'chad'
The output is:
=================================== FAILURES ===================================
_____________________________ TestThings.test_user _____________________________
self = <tests.test_again.TestThings instance at 0x10aed6998>
def test_user(self):
> assert user_setup['name'] == 'chad'
E TypeError: 'function' object has no attribute '__getitem__'
tests/test_again.py:14: TypeError
=========================== 1 failed in 0.02 seconds ===========================
But if I rewrite my test so that it doesn't use the usefixtures
decorator, it works as expected:
def test_user(user_setup):
assert user_setup['name'] == 'chad'
Any ideas why it's not working when I try to use the decorator method?
When you use the @pytest.mark.usefixtures
marker you still need to provide a similarly named input argument if you want that fixture to be injected in to your test function.
As described in the py.test docs for fixtures:
The name of the fixture function can later be referenced to cause its invocation ahead of running tests... Test functions can directly use fixture names as input arguments in which case the fixture instance returned from the fixture function will be injected.
So just using the @pytest.mark.usefixtures
decorator will only invoke the function. Providing an input argument will give you the result of that function.
You only really need to use @pytest.mark.usefixtures
when you want to invoke a fixture but don't want to have it as an input argument to your test. As described in the py.test docs.
The reason you are getting an exception that talks about user_setup
being a function is because inside your test_user
function the name user_setup
actually refers to the function you defined earlier in the file. To get your code to work as you expect you would need to add an argument to the test_user function:
@pytest.mark.usefixtures('user_setup')
class TestThings:
def test_user(self, user_setup):
assert user_setup['name'] == 'chad'
Now from the perspective of the test_user function the name user_setup
will refer to the function argument which will be the returned value of the fixture as injected by py.test.
But really you just don't need to use the @pytest.mark.usefixtures
decorator at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With