pythonpytestpytest-asynciopytest-fixtures

ScopeMismatch when i try to make setup_teardown pytest function


My goal is to create a fixture that will run once at the beginning of the class function test and initialize the attributes I need in self. To do this, I created a fixture with the scope of the class and applied it directly to the class. To solve the compatibility problem of pytest with asynchronous code, pytest-asyncio was used.

My minimally reproducible example:

import pytest


@pytest.fixture(scope="class")
async def setup_teardown(request):
    request.cls.test_number = '123'
    yield
    # ...


@pytest.mark.asyncio
@pytest.mark.usefixtures("setup_teardown")
class Test_BaseFunctional():

    async def test_my_number(self):
        assert self.test_number == '123'

But i'm receiving:

ScopeMismatch: You tried to access the function scoped fixture event_loop with a class scoped request object, involved factories:
tests/issue.py:4:  def setup_teardown(request)

I tried many ways, from time to time I got a large-scale non-working code, and in the end I returned to this minimal example in the hope of help from you, dear friends.


Solution

  • The reason was in pytest-asyncio fixtures realization. They has scope "function" which not implicated with higher-level fixtures, such as the scope "class". In this case, we just need to redefine event_loop fixture to eliminate ScopeMismatch.

    @pytest.fixture(scope="class")
    def event_loop():
        policy = asyncio.get_event_loop_policy()
        loop = policy.new_event_loop()
        yield loop
        loop.close()
    

    You can put this code into coftest.py file.