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

如何用pytest测试上下文管理器退出阶段抛出的指定异常?

验证上下文管理器退出阶段抛出指定异常的pytest解决方案

原代码的问题在于:pytest.raises会捕获整个嵌套块内的所有Foo异常——包括上下文管理器初始化(__init__)或进入(__enter__)阶段抛出的异常,导致测试错误通过,而我们真正要验证的是**退出阶段(__exit__)**抛出的异常。

以下是两种可行的解决方案,无需依赖外部工具:

方案1:用contextlib.ExitStack拆分进入与退出逻辑

借助标准库的ExitStack,可以先安全完成上下文的进入操作(确保此阶段无异常),再主动触发退出并捕获目标异常,精准验证退出阶段的行为:

from contextlib import ExitStack
import pytest

def test_context_manager_exits_with_foo():
    with ExitStack() as stack:
        # 进入上下文管理器,若初始化/进入阶段抛Foo,测试直接失败
        stack.enter_context(my_context_mngr())
        # 主动触发所有上下文的退出流程,捕获Foo异常
        with pytest.raises(Foo):
            stack.pop_all()

方案2:显式控制上下文的每个阶段(直接调用特殊方法)

如果需要完全掌控上下文的实例化、进入、退出步骤,可以直接调用上下文管理器的特殊方法,明确区分各阶段的异常:

import pytest

def test_context_manager_exits_with_foo():
    # 实例化上下文,若__init__抛Foo,测试失败
    cm = my_context_mngr()
    try:
        # 进入上下文,若__enter__抛Foo,测试失败
        cm.__enter__()
        # 执行上下文内的业务逻辑(此处为空操作)
    finally:
        # 验证退出阶段抛出Foo异常
        with pytest.raises(Foo):
            cm.__exit__(None, None, None)

方案1通过ExitStack封装了上下文管理细节,更符合Python的惯用写法;方案2则更直观,适合需要精细控制每个阶段的测试场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:23:13