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

pytest测试async context manager fixture返回意外async_generator对象

在pytest fixture中使用异步上下文管理器返回async_generator而非实例的解决办法

问题重现

定义异步上下文管理器类后,在pytest fixture中通过async with+yield返回实例,但测试函数中拿到的是async_generator对象,调用方法时报错:

AttributeError: 'async_generator' object has no attribute 'add_numbers'

相关代码:

import asyncio
import pytest

class MyAsyncContextManager:
    async def __aenter__(self):
        print("Entering async context")
        return self

    async def __aexit__(self, exc_type, exc, tb):
        print("Exiting async context")

    def add_numbers(self, a, b):
        return a + b
    
@pytest.fixture
async def async_context_manager():
    async with MyAsyncContextManager() as manager:
        yield manager

@pytest.mark.asyncio
async def test_async_context_manager(async_context_manager):
    async_context_manager.add_numbers(1, 2)

原因分析

使用普通的@pytest.fixture装饰带yield的异步函数时,pytest不会自动解析异步生成器的产出值,而是直接将生成器对象注入测试函数,导致无法直接调用实例方法。

解决方法

方法1:使用pytest-asyncio的专用fixture装饰器

先安装pytest-asyncio(如果未安装):

pip install pytest-asyncio

将fixture的装饰器替换为@pytest_asyncio.fixture,pytest会自动处理异步生成器,把yield的实例注入测试函数:

import pytest_asyncio

@pytest_asyncio.fixture
async def async_context_manager():
    async with MyAsyncContextManager() as manager:
        yield manager

@pytest.mark.asyncio
async def test_async_context_manager(async_context_manager):
    assert async_context_manager.add_numbers(1, 2) == 3

方法2:手动迭代异步生成器获取实例

如果不想依赖pytest_asyncio的专用装饰器,可在测试函数中通过await anext()手动获取异步生成器的产出值:

@pytest.mark.asyncio
async def test_async_context_manager(async_context_manager):
    manager = await anext(async_context_manager)
    assert manager.add_numbers(1, 2) == 3

方法3:fixture返回上下文管理器实例,测试中手动管理上下文

将fixture改为直接返回上下文管理器实例,在测试函数中通过async with自行控制上下文的进入和退出:

@pytest.fixture
def async_context_manager():
    return MyAsyncContextManager()

@pytest.mark.asyncio
async def test_async_context_manager(async_context_manager):
    async with async_context_manager as manager:
        assert manager.add_numbers(1, 2) == 3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 03:27:23