I have code that uses Twisted so I've written a test function for it and decorated it with @pytest_twisted.ensureDeferred
. The function awaits on some Deferreds. Then, I need to run some aiohttp
website in it so I've written a fixture that uses the pytest_aiohttp.plugin.aiohttp_client
fixture, decorated it with @pytest_asyncio.fixture
and used it in my test function. The result doesn't work (probably because I need to make Twisted and aiohttp use the same event loop or something like that?). Specifically, it prints "twisted/internet/asyncioreactor.py:50: DeprecationWarning: There is no current event loop" and then crashes with the following exception:
.env/lib/python3.13/site-packages/pytest_twisted/__init__.py:343: in _run_inline_callbacks
_instances.reactor.callLater(0.0, in_reactor, d, f, *args)
.env/lib/python3.13/site-packages/twisted/internet/asyncioreactor.py:289: in callLater
self._reschedule()
.env/lib/python3.13/site-packages/twisted/internet/asyncioreactor.py:279: in _reschedule
self._timerHandle = self._asyncioEventloop.call_at(abs_time, self._onTimer)
/usr/lib/python3.13/asyncio/base_events.py:812: in call_at
self._check_closed()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <_UnixSelectorEventLoop running=False closed=True debug=False>
def _check_closed(self):
if self._closed:
> raise RuntimeError('Event loop is closed')
E RuntimeError: Event loop is closed
/usr/lib/python3.13/asyncio/base_events.py:556: RuntimeError
As the actual test function is not even executed its content doesn't seem to matter, and custom fixtures also aren't needed for this to fail so here is a minimal one that shows the problem:
@ensureDeferred
async def test_minimal(aiohttp_client):
app = web.Application()
await aiohttp_client(app)
My settings:
[tool.pytest.ini_options]
addopts = [
"--reactor=asyncio",
]
asyncio_mode = "strict"
asyncio_default_fixture_loop_scope = "function"
(not 100% sure about these, but I think moving to asyncio_mode = "auto"
and replacing @pytest_asyncio.fixture
with @pytest.fixture
can only make it worse, and changing the fixture loop scope to "module"
makes the runner hang before doing anything).
What is the correct way to write such test functions, assuming it exists?