[Python3高阶编程] - 异步编程深度学习指南四:pytest中如何调试异步编程(asyncio)
·
在 pytest 中调试异步代码有几种方法,以下是最推荐和实用的方案:
方案一:使用 pytest-asyncio + breakpoint()(推荐)
1. 安装依赖
pip install pytest-asyncio
2. 在异步代码中使用 breakpoint()
import asyncio
import pytest
@pytest.mark.asyncio
async def test_async_function():
x = await some_async_operation()
# 设置断点 - 这是最简单的方法
breakpoint()
assert x == expected_value
async def some_async_operation():
await asyncio.sleep(1)
return "result"
3. 运行测试
# 正常运行,遇到 breakpoint() 会进入调试器 pytest -v test_file.py::test_async_function # 或者启用 pdb 模式 pytest --pdb test_file.py::test_async_function
方案二:使用 aiodebug 库(专门用于异步调试)
1. 安装
pip install aiodebug
2. 使用示例
import asyncio
import aiodebug
import pytest
@pytest.mark.asyncio
async def test_with_aiodebug():
# 启用异步调试支持
aiodebug.enable()
result = await some_async_function()
# 现在可以正常使用 pdb
import pdb; pdb.set_trace()
assert result is not None
方案三:手动创建调试事件循环
如果不想安装额外依赖,可以手动处理:
import asyncio
import pytest
@pytest.mark.asyncio
async def test_manual_debug():
result = await some_async_function()
# 手动进入调试器
import sys
if sys.gettrace() is not None: # 检查是否在调试模式
import pdb; pdb.set_trace()
# 或者直接使用(在 pytest 中通常有效)
import pdb; pdb.set_trace()
assert result == "expected"
方案四:使用 VS Code 调试器(开发环境推荐)
1. 配置 .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: pytest",
"type": "python",
"request": "launch",
"program": "${env:PYTHONPATH}/bin/pytest",
"args": [
"-v",
"${file}"
],
"console": "integratedTerminal",
"justMyCode": true,
"env": {
"PYTHONASYNCIODEBUG": "1"
}
}
]
}
2. 在代码中设置断点
直接在 VS Code 中点击行号左侧设置断点,然后按 F5 调试。
方案五:使用 debugpy(适用于远程调试)
import debugpy
import asyncio
import pytest
@pytest.mark.asyncio
async def test_with_debugpy():
# 启动调试服务器(可选)
# debugpy.listen(5678)
# debugpy.wait_for_client()
result = await some_async_function()
# 设置断点
debugpy.breakpoint()
assert result is not None
常见问题和解决方案
问题1:pdb.set_trace() 导致事件循环挂起
原因:pdb 是同步的,会阻塞异步事件循环。
解决方案:使用 breakpoint() 或确保在 pytest-asyncio 环境中运行。
问题2:断点不生效
检查清单:
- 确保测试函数有
@pytest.mark.asyncio装饰器 - 确保安装了
pytest-asyncio - 确保没有设置
PYTHONBREAKPOINT=0
问题3:需要在 fixture 中调试
@pytest.fixture
async def async_fixture():
result = await setup_async_resource()
# 可以在这里调试
breakpoint()
yield result
await cleanup_async_resource()
最佳实践建议
- 开发阶段:使用 VS Code + pytest-asyncio 组合
- 命令行调试:直接使用
breakpoint()最简单 - 生产调试:避免在生产代码中保留调试语句
- 团队协作:在
.gitignore中添加调试相关的临时文件
完整示例
# test_async_debug.py
import asyncio
import pytest
async def fetch_data(url):
await asyncio.sleep(0.1) # 模拟网络请求
return f"Data from {url}"
@pytest.mark.asyncio
async def test_fetch_data():
url = "https://example.com"
# 方法1: 使用 breakpoint() (Python 3.7+)
breakpoint()
# 方法2: 使用 pdb (传统方式)
# import pdb; pdb.set_trace()
result = await fetch_data(url)
assert "example.com" in result
运行命令:
pytest -v test_async_debug.py::test_fetch_data
这样就能像调试同步代码一样调试异步代码了!
更多推荐


所有评论(0)