Repository: pytest-dev/pytest-asyncio

Issue #197: async method fixture is run with different `self` than the test method
Created: 2020-11-10T20:11:53Z
Hi,
I just ran into this - if you make a fixture method async, it is run with a different self, so you can't set attributes on self and read them in test methods. Here is a simple snippet to reproduce the problem:
import pytest

pytestmark = pytest.mark.asyncio

class TestAsyncFixture:
  @pytest.fixture #(autouse = True)
  async def setup(self):
    # await self.client._handle_ws_request(self.payment_start_request)
    self.some_attr = 'value'

    print()
    print('in fixture')
    print(self)
    print(self.__dict__)

  async def test_response(self, setup):
    print('in test')
    print(self)          # different object
    print(self.__dict__) # some_attr missing
At first, I thought this only concerns autouse fixtures, but now I tried using it without autouse and it has the same problem. Is this a known issue, or is it supposed to work?
I'm using
python            3.8.3
pytest            6.1.2
pytest-asyncio    0.14.0

Btw, thanks for this great library, I'm using it heavily and it's been of great help.

Duplicate issue #297: Asynchronous fixtures in a class do not work like normal fixtures.
Created: 2022-02-22T11:17:27Z
python 3.9.9
pytest 6.2.5
pytest-asyncio 0.18.1
import pytest
import pytest_asyncio

The following test passes.
class TestClass:
    @pytest.fixture()
    def init(self):
        self.X = True
    
    async def test_function(self, init):
        assert self.X is True

However, the following test do not pass.
class TestClassAsync:
    @pytest_asyncio.fixture()
    async def init(self):
        self.X = True
    
    async def test_function(self, init):
        assert self.X is True

=================================================================================================================== FAILURES ===================================================================================================================
_________________________________________________________________________________________________________ TestClassAsync.test_function _________________________________________________________________________________________________________ 

self = <pytest_test.TestClassAsync object at 0x0000027E9D82ECA0>, init = None

    async def test_function(self, init):
>       assert self.X is True
E       AttributeError: 'TestClassAsync' object has no attribute 'X'

pytest_test.py:27: AttributeError

If the following changes are made, the test passes.
class TestClassAsync2:        
    @pytest.fixture()    
    def init(self, event_loop:asyncio.BaseEventLoop):
        event_loop.run_until_complete(self.init_async())
    
    async def init_async(self):
        self.X = True
    
    async def test_function(self, init):
        assert self.X is True


But this seems a bit tedious; is it possible to get the second test to pass? Or is there an easier way?

Closing comment (2022-02-22T11:28:41Z): Thanks @34j for the report! This seems to be a duplicate of #197.
Unfortunately, I can't provide a workaround for the issue at the moment. The only other way I can think of is this:
class TestClassAsync:
    @pytest_asyncio.fixture()
    async def init(self):
        return True
    
    async def test_function(self, init):
        assert init is True

My example doesn't rely on self. The fixture returns its value directly rather than setting self.X. This should work until the issue is fixed.