Skip to content

Testing and Debugging

Async bugs are often timing bugs, which means they do not always reproduce the same way twice. That is why async testing needs timeout guards, task-leak checks, and debug mode rather than only happy-path assertions.

Quick takeaway: do not just assert the final value. Use timeout guards to fail hangs, enable debug mode to surface misuse, and check that no extra tasks survive when the test is done.

Debugging Flow

Async debugging is about observability: force bounded execution time, enable debug mode, inspect tasks, then fix cleanup or blocking paths.

First Guardrail to Add

py
import asyncio


async def fetch_with_guard() -> str:
    async with asyncio.timeout(0.5):
        await asyncio.sleep(0.1)
        return "ok"


def main() -> None:
    runner = asyncio.Runner(debug=True)
    with runner:
        print(runner.run(fetch_with_guard()))


if __name__ == "__main__":
    main()

`asyncio.timeout()` turns hangs into failures, while `Runner(debug=True)` or `asyncio.run(..., debug=True)` enables additional debug checks and warnings.

Simple Task-Leak Check

py
import asyncio


async def assert_no_extra_tasks() -> None:
    current = asyncio.current_task()
    leaked = {
        task
        for task in asyncio.all_tasks()
        if task is not current and not task.done()
    }
    if leaked:
        raise AssertionError(f"leaked tasks: {leaked}")

What Debug Mode Helps Surface

  • forgotten awaits
  • wrong thread usage of loop APIs
  • slow callbacks and selector operations
  • unclosed transports or resource warnings

Checklist

Every test gets a timeout

Hangs are worse than ordinary failures. Always bound execution time.

Verify cleanup paths

Cancellation should leave queues, semaphores, and background tasks in a clean state.

Use debug mode intentionally

Debug mode is excellent for local reproduction and CI diagnosis of subtle async issues.

Inspect pending tasks

Checking for leftover tasks catches leaks early.

Official Sources

Built with VitePress for a Python 3.14 handbook.