Skip to content

Asynchronous fixtures in a class do not work like normal fixtures. #297

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

Closed
34j opened this issue Feb 22, 2022 · 2 comments
Closed

Asynchronous fixtures in a class do not work like normal fixtures. #297

34j opened this issue Feb 22, 2022 · 2 comments

Comments

@34j
Copy link

34j commented Feb 22, 2022

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?

@34j 34j changed the title Asynchronous fixtures in a class do not work properly. Asynchronous fixtures in a class do not work like normal fixtures. Feb 22, 2022
@seifertm
Copy link
Contributor

seifertm commented Feb 22, 2022

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.

@Arseniy-Popov
Copy link

This workaround seems to work fine:

class Test:
    @pytest.fixture
    async def setup(self):
        self.a = True
        return self.__dict__

    async def test(self, setup):
        self.__dict__ = setup
        assert self.a is True

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

No branches or pull requests

3 participants