pytest-asyncio
pytest plugin for testing asyncio code. Required for async def test_ functions — pytest does not run them natively. Has undergone multiple breaking redesigns around event loop scoping. Current version is 1.3.0 (2026). Has a long history of yanked releases and sudden breaking changes.
Warnings
- breaking asyncio_mode must be explicitly set. There is no safe default — omitting it causes a DeprecationWarning and the default changed from 'legacy' to 'strict' in 0.21. LLM-generated configs often omit this entirely.
- breaking legacy mode removed in 0.23. Any codebase relying on asyncio_mode=legacy (the old default) will fail after upgrading past 0.21.
- breaking Custom event_loop fixture redefinition removed in 1.x. A very common pattern in older tutorials — defining a session-scoped event_loop fixture — now raises an error.
- breaking @pytest.asyncio_event_loop mark removed. Was used for class/module-scoped event loops.
- gotcha Async fixtures must use @pytest_asyncio.fixture, not @pytest.fixture. Using @pytest.fixture on an async function works in auto mode but emits warnings and fails in strict mode.
- gotcha async def test_ functions silently appear to pass without actually running in strict mode if @pytest.mark.asyncio is missing. No error is raised — the test is collected and marked as passed.
- gotcha Several versions in the 0.22-0.24 range were yanked from PyPI due to fundamental event loop scoping bugs. Pinning to a yanked version will fail at install time.
Install
-
pip install pytest-asyncio
Imports
- pytest_asyncio.fixture
import pytest_asyncio @pytest_asyncio.fixture async def my_async_fixture(): return await setup_something() - asyncio mark
@pytest.mark.asyncio async def test_something(): await asyncio.sleep(0)
Quickstart
# pytest.ini or pyproject.toml — REQUIRED configuration
# [pytest]
# asyncio_mode = auto
# With asyncio_mode=auto, no per-test marks needed:
import pytest_asyncio
@pytest_asyncio.fixture
async def async_client():
client = await create_client()
yield client
await client.close()
async def test_something(async_client):
result = await async_client.fetch()
assert result is not None
# Without asyncio_mode=auto, mark each test explicitly:
import pytest
@pytest.mark.asyncio
async def test_explicit():
await asyncio.sleep(0)