PYTHON Contents

Testing Async Code (pytest-asyncio)

Test async code with pytest correctly: await coroutines, control timeouts, and ensure tasks are not leaking across tests.

On this page

Async Tests Need Explicit Control

Async tests must await all work and enforce timeouts. Leaked tasks cause flaky builds and mysterious failures.

Async Test Pattern

import asyncio

async def work() -> str:
    await asyncio.sleep(0.01)
    return "ok"

def test_work():
    out = asyncio.run(work())
    assert out == "ok"

Timeout Guard

import asyncio

async def slow():
    await asyncio.sleep(10)

def test_timeout():
    with pytest.raises(asyncio.TimeoutError):
        asyncio.run(asyncio.wait_for(slow(), timeout=0.05))

Operational Checklist

  • Always await tasks or explicitly cancel them at test end.
  • Use timeouts to prevent hung CI runs.
  • Keep async tests deterministic (no real network unless integration).

Failure Modes

  • Task leaks: background tasks continue into the next test.
  • Hung builds: missing timeouts cause indefinite CI waits.