pytest-asyncio-cooperative
raw JSON → 0.40.0 verified Fri May 01 auth: no python
A pytest plugin that runs all async tests cooperatively using a single event loop, avoiding event loop conflicts and improving performance. Current version: 0.40.0, requires Python >=3.8. Released under MIT license; maintenance cadence is irregular.
pip install pytest-asyncio-cooperative Common errors
error RuntimeError: There is no current event loop in thread 'MainThread' ↓
cause Missing session-scoped event_loop fixture.
fix
Add a session-scoped event_loop fixture in conftest.py:
@pytest.fixture(scope="session")
def event_loop():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
yield loop
loop.close()
error Fixture 'event_loop' cannot be a session-scoped fixture because it is defined in a non-top-level conftest ↓
cause The event_loop fixture is defined in a conftest.py inside a subpackage, but pytest-asyncio-cooperative expects it at the root conftest or the test directory.
fix
Move the event_loop fixture to the root conftest.py (or ensure the conftest.py is in the top-level test directory).
error AttributeError: module 'pytest' has no attribute 'mark' ↓
cause Attempting to import pytest.mark without the marker being registered.
fix
Ensure pytest-asyncio-cooperative is installed and the conftest.py is found. The marker is automatically registered when the plugin is active.
error DeprecationWarning: The 'event_loop' fixture is deprecated ↓
cause Using an older version of pytest-asyncio that suppresses the warning, but pytest-asyncio-cooperative may use the old fixture pattern.
fix
Upgrade pytest-asyncio and pytest-asyncio-cooperative to latest versions. If the warning persists, use scope='session' event_loop fixture as recommended.
Warnings
gotcha The marker is @pytest.mark.asyncio_cooperative, not @pytest.mark.asyncio. Using the wrong marker will run tests in isolated loops and may cause event loop conflicts. ↓
fix Use @pytest.mark.asyncio_cooperative instead of @pytest.mark.asyncio.
gotcha The plugin requires a session-scoped event_loop fixture. If you forget to define it, you may get 'RuntimeError: There is no current event loop in thread'. ↓
fix Define a session-scoped event_loop fixture in conftest.py that creates a new event loop.
gotcha Tests that call loop.run_until_complete() or create sub-loops may interfere with the shared loop. Avoid mixing cooperative tests with those that manage their own loops. ↓
fix Ensure all async tests within the session use the same event loop; do not create new loops manually.
Imports
- pytest.mark.asyncio_cooperative
from pytest_asyncio_cooperative import pytest_configure - pytest_configure wrong
import pytest_asyncio_cooperativecorrectfrom pytest_asyncio_cooperative import pytest_configure
Quickstart
# conftest.py
import asyncio
import sys
@pytest.fixture(scope="session")
def event_loop():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
yield loop
loop.close()
# test_async.py
import pytest
@pytest.mark.asyncio_cooperative
async def test_async_example():
await asyncio.sleep(0.1)
assert True