You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决unittest.TestCase异步测试中RuntimeWarning协程未等待错误

异步测试运行失败问题解决

我在运行异步unittest测试时遇到问题,示例代码如下:

import unittest
import asyncio
from asyncio import coroutine
import pytest
import os


class TestEcommerce(unittest.TestCase):

    async def assertFloatAlmostEqual(self, first, second, places=2, msg=""):
        """
        用于按指定精度比较浮点数值。
        每次测试得到的数值精度可能略有差异,但这不属于错误
        :param msg:
        :param first:
        :param second:
        :param places:
        :return:
        """
        self.assertAlmostEqual(first, second, places=places, msg=msg)

    @pytest.mark.asyncio
    async def test_deep_analysis_find_complex(self):
        # 示例代码
        await self.assertFloatAlmostEqual(100.44, 100.445)
        pass

运行后报错:

kernel/test/test_demo.py::TestEcommerce::test_deep_analysis_find_complex
/usr/lib/python3.10/unittest/case.py:549: RuntimeWarning: coroutine 'TestEcommerce.test_deep_analysis_find_complex' was never awaited
method() Enable tracemalloc to get traceback where the object was allocated.

-- Docs: pytest警告捕获相关文档

我试过查看同类问题但解决方案无效,还尝试移除测试函数的async关键字,出现预期内的语法错误:

修改后的代码:

@pytest.mark.asyncio
def test_deep_analysis_find_complex(self):
    # 示例代码
    await self.assertFloatAlmostEqual(100.44, 100.445)
    pass

对应错误:

E await self.assertFloatAlmostEqual(100.44, 100.445)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E SyntaxError: 'await' outside async function

我的环境信息:
执行pip list --format=freeze | grep pytest输出:

pytest7.4.0
pytest-asyncio
0.21.1

执行python -V输出:

Python 3.10.6


问题原因

混用unittest.TestCase类与pytest-asyncio的@pytest.mark.asyncio装饰器,unittest.TestCase的测试方法不兼容该装饰器的异步调度逻辑,导致协程未被正确执行。

解决方法

方案1:改用pytest原生测试类(不继承unittest.TestCase)

将测试类改为普通类,无需继承unittest.TestCase,让pytest-asyncio正常处理异步测试:

import pytest


class TestEcommerce:

    def assertFloatAlmostEqual(self, first, second, places=2, msg=""):
        # 无需async,直接实现近似断言
        assert abs(first - second) < 10**(-places), msg or f"{first} 与 {second} 在{places}位精度下不相等"
        # 也可直接用pytest内置断言:
        # assert first == pytest.approx(second, rel=10**(-places))

    @pytest.mark.asyncio
    async def test_deep_analysis_find_complex(self):
        # 断言方法非协程,无需await
        self.assertFloatAlmostEqual(100.44, 100.445)

方案2:保留unittest.TestCase,用asyncio.run手动执行协程

如果必须继承unittest.TestCase,可在普通测试方法内定义异步逻辑并通过asyncio.run执行:

import unittest
import asyncio


class TestEcommerce(unittest.TestCase):

    def assertFloatAlmostEqual(self, first, second, places=2, msg=""):
        self.assertAlmostEqual(first, second, places=places, msg=msg)

    def test_deep_analysis_find_complex(self):
        async def async_test_logic():
            # 这里可放入真正的异步操作
            self.assertFloatAlmostEqual(100.44, 100.445)
        
        asyncio.run(async_test_logic())

额外提示

你的assertFloatAlmostEqual方法本身没有异步操作,完全不需要定义为async方法——只有包含异步调用(如await其他协程)的方法才需要设为协程,避免不必要的await操作。


内容的提问来源于stack exchange,提问作者stas stas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:02:05