Description
pytest-asyncio v0.24 supports independent event-loop scopes and fixture caching scopes. This is great, thank you. However, I had some confusion while working with this. I thought I'd share in case there's an elegant solution I've not spotted.
The following works fine:
import asyncio
import pytest
import pytest_asyncio
loop: asyncio.AbstractEventLoop | None = None
@pytest_asyncio.fixture(loop_scope="session")
async def loop_fixture():
global loop
loop = asyncio.get_running_loop()
@pytest_asyncio.fixture(loop_scope="session", scope="function")
async def another_fixture():
return "foo"
@pytest.mark.asyncio(loop_scope="session")
async def test_a(loop_fixture, another_fixture):
global loop
assert loop == asyncio.get_running_loop()
assert another_fixture == "foo"
and with a minor change I've convinced myself that another_fixture
really is function-scoped. All good.
However, if I have pyproject.toml
containing:
[tool.pytest.ini_options]
asyncio_default_fixture_loop_scope = "session"
my initial (hopeful) expectation was that I would not need to write loop_scope="session"
everywhere, but this is mistaken:
import asyncio
import pytest
import pytest_asyncio
loop: asyncio.AbstractEventLoop | None = None
@pytest_asyncio.fixture
async def loop_fixture():
global loop
loop = asyncio.get_running_loop()
@pytest_asyncio.fixture(scope="function")
async def another_fixture():
return "foo"
@pytest.mark.asyncio
async def test_a(loop_fixture, another_fixture):
global loop
assert loop == asyncio.get_running_loop()
assert another_fixture == "foo"
with error:
E pytest_asyncio.plugin.MultipleEventLoopsRequestedError: Multiple asyncio event loops with different scopes have been requested
Of course, the solution is to omit loop_scope="session"
only the fixtures, but keep it on the test function itself like:
@pytest.mark.asyncio(loop_scope="session")
async def test_a(loop_fixture, another_fixture):
...
but in a suite of many tests, it's boilerplate.
I've understood asyncio_default_fixture_loop_scope
was intended to relieve such boilerplate on the fixtures, but is there something similar possible for the tests themselves? I know I could write a hook to add this marker to the tests, but my gut feeling says this magic would confuse later. On the other hand, I could imagine some config like asyncio_default_test_loop_scope
... is there something neat I've missed?