python 3.10+ 异步测试报错主因是 pytest-asyncio 版本<0.21.0、未配置 asyncio_mode="auto"、未加 @pytest.mark.asyncio 装饰器,导致协程未 await 或事件循环关闭;三步修复:升级插件、显式配置、强制装饰。

Python 3.10+ 中异步测试报错,绝大多数不是语法问题,而是 pytest-asyncio 插件版本、事件循环生命周期和装饰器缺失三者叠加导致的——RuntimeWarning: coroutine 'test_xxx' was never awaited 或 Event loop is closed 这类错误,90% 都能靠三步 fix。
pytest-asyncio 版本必须 ≥0.21.0
旧版 pytest-asyncio 在 Python 3.10+ 中仍用已弃用的 <code>asyncio.get_event_loop(),会触发 DeprecationWarning,严重时直接崩溃。这不是警告,是兼容性断裂点。
- 必须执行:
pip install -U pytest-asyncio>=0.21.0(推荐0.23.0+) - 检查是否生效:
pytest --version输出里应含pytest-asyncio-0.23.x - 如果项目用
pyproject.toml,确认有:asyncio_mode = "auto"(新版默认,但显式声明更稳)
@pytest.mark.asyncio 是强制要求,不是可选装饰
不加这个装饰器,pytest 就把 async def test_xxx() 当普通函数执行,协程对象根本不会被 await,直接变成“未执行计划”。
- 错误写法:
async def test_fetch(): ...(没装饰 → 报was never awaited) - 正确写法:
@pytest.mark.asyncio必须紧贴函数上方 - 别依赖函数名含
async或文件名带_async—— 这些都不触发自动识别
fixture 里不能裸返回协程对象
同步 fixture 里直接写 return asyncio.sleep(0.1),等于扔出一个未 await 的协程对象,下游用它的地方一调就崩。
- 错误模式:
@pytest.fixture函数里return some_async_func() - 正确解法有两种:
– 改用@pytest.fixture(scope="function", autouse=True)+ 手动await初始化逻辑
– 或改用async deffixture(需配合@pytest.mark.asyncio测试函数使用,且 fixture 本身不支持该装饰器,得靠测试函数驱动) - 简单验证:打印
type(your_fixture_result),如果是<class></class>,就必须await
最易被忽略的是:pytest-asyncio 的 asyncio_mode = "auto" 只对函数名匹配 ^test 且含 async def 生效,但一旦夹杂了非标准命名、嵌套调用或 fixture 传参链,隐式行为就会失效——这时候不加 @pytest.mark.asyncio 就等于没写异步。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











