event_loop_policy for single test
Opened this issue · 6 comments
It would be good if there was an easy way to change the event_loop_policy for a single test. I can't see any way to do this currently from the documentation (other than moving a single test to it's own module).
In aiohttp, we currently have these fixtures in conftest.py, which I'm looking to remove:
@pytest.fixture
def selector_loop() -> Iterator[asyncio.AbstractEventLoop]:
policy = asyncio.WindowsSelectorEventLoopPolicy() # type: ignore[attr-defined]
asyncio.set_event_loop_policy(policy)
with loop_context(policy.new_event_loop) as:
asyncio.set_event_loop(_loop)
yield _loop
@pytest.fixture
def uvloop_loop() -> Iterator[asyncio.AbstractEventLoop]:
policy = uvloop.EventLoopPolicy()
asyncio.set_event_loop_policy(policy)
with loop_context(policy.new_event_loop) as:
asyncio.set_event_loop(_loop)
yield _loop
That makes sense. The event loop policy support is not in a good state, unfortunately. I think this is closely related to #796.
I'm also linking #1032 which argues that this kind of customization should be possible through the async marker.
For example: @pytest.mark.asyncio(policy=…).
It's also worth mentioning that upstream is deprecating the policy system and looking to remove it entirely:
python/cpython#127949
I think this is closely related to #796.
That one seems to just be concerned with sync tests geting executed multiple times.
I'm also linking #1032 which argues that this kind of customization should be possible through the async marker.
For example:@pytest.mark.asyncio(policy=…).
Yes, this one may end up solving the issue.
There's a draft PR that aims to provide a loop_factory argument to pytest.mark.asyncio and pytest_asyncio.fixture, in order to control the loop factory/policy used for tests and fixtures. However, it turns out that would entail a very complex mechanism to track loop factories across tests and fixtures.
Therefore, my current idea is to provide a simpler way of parametrizing tests over multiple types of event loops. Specifically, I'm thinking about having a single set of loop factories in pyproject.toml or pytest.ini that parametrizes all tests.
@Dreamsorcerer If pytest-asyncio provided some mechanism to limit test parametrizations to certain pytest node IDs or skip tests that are not wanted, do you think that approach would be usable for you?
I'm not too clear exactly how that would work. If the mechanism allows us to skip the ~4000 tests that don't need those loops without modifying all those tests, then it might work (though might confuse some people when they see 8000 skipped tests in the pytest output).
Checking the code, we literally have only 2 tests that use the selector_loop fixture and 1 test that uses the uvloop_loop fixture. All other tests should use the default loop.
We also have a proactor_loop used in about 5 tests.
limit test parametrizations to certain pytest node IDs
If you mean certain tests would be run with all loops, that wouldn't work. Every test should be run once, with a particular loop.