Parametrizing `event_loop_policy` parametrizes all tests
aceg1k opened this issue · 2 comments
Contrary to the statements in the documentation (here and here), the fixture is not only applied to all pytest-asyncio tests, but also applied to all other tests.
import asyncio
import pytest
import uvloop
@pytest.fixture(
scope="session",
params=(asyncio.get_event_loop_policy(), uvloop.EventLoopPolicy()),
ids=("asyncio", "uvloop"),
)
def event_loop_policy(request):
return request.param
@pytest.mark.asyncio
async def test_async():
pass
def test_sync():
passOutput:
plugins: asyncio-0.23.5
asyncio: mode=Mode.STRICT
collected 4 items
test_event_loop_policy.py::test_async[asyncio] PASSED [ 25%]
test_event_loop_policy.py::test_sync[asyncio] PASSED [ 50%]
test_event_loop_policy.py::test_async[uvloop] PASSED [ 75%]
test_event_loop_policy.py::test_sync[uvloop] PASSED [100%]
Thanks for the report and the reproducer!
The event loop policy fixture is defined as an autouse fixture. I don't exactly recall why, but I think the reason is that it's now used by the deprecated event_loop fixture and had to be marked as autouse for backwards compatibility.
It's obviously a bug that this also parametrizes all sync tests and needs to be addressed.
However, I don't expect this issue to be fixed before v1.0 when the legacy event_loop fixture is gone.
Ran into this today. Unfortunately, this means that event_loop_policy is useless for me. So the easiest way is to go back to event_loop:
import asyncio
import contextlib
import warnings
import pytest
import uvloop
@pytest.fixture(
scope="session",
params=(asyncio.get_event_loop_policy(), uvloop.EventLoopPolicy()),
ids=("asyncio", "uvloop"),
)
def policy(request):
warnings.filterwarnings('ignore', "The event_loop fixture")
return request.param
@pytest.fixture
def event_loop(policy):
with contextlib.closing(policy.new_event_loop()) as loop:
yield loop
@pytest.mark.asyncio
async def test_async(policy):
pass
def test_sync():
passNote that you must parametrize your async tests by policy in some way, otherwise you will get The requested fixture has no parameter defined for test. This is because event_loop is requested using request.getfixturevalue, so pytest doesn't know that it should create two runs of test_async, and when event_loop is requested it is too late. In my case I was already requesting policy in all my tests anyway, but this may be more annoying for you.