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

如何为抛出含字符串信息的异常编写pytest测试用例?

如何正确编写pytest测试用例捕获自定义异常?

你的测试代码里有几个关键问题,导致PyCharm报错且测试逻辑不正确,我来一步步帮你修正:

先明确错误根源

  1. pytest.raises()参数类型错误:你传了字符串e给它,但这个方法需要的是异常类型(比如Exception)或者异常类型的元组,不是异常消息字符串——这就是PyCharm提示类型不匹配的核心原因。
  2. 异常捕获后的断言逻辑错误:当check()抛出异常时,函数不会返回任何值,res根本不会被赋值,所以assert res == e这行代码永远不会执行,反而会导致测试失败。
  3. 未控制依赖变量someMap:原函数依赖全局变量someMap,测试时必须明确设置它的状态,否则测试结果会受外部环境影响,完全不稳定。

修正后的完整测试用例

假设someMap是全局变量,我们可以这样写测试:

import pytest

# 原函数(为了测试完整性,这里一并包含)
def check():
    if 'connector' in someMap:
        print("proceed")
    else:
        raise Exception('Positive vibes only')
    return 1

# 全局变量初始化
someMap = {}

# 测试正常分支:存在connector键
def test_check_with_connector():
    global someMap
    someMap = {'connector': 'any_value'}
    result = check()
    assert result == 1

# 测试异常分支:不存在connector键
def test_check_without_connector():
    global someMap
    someMap = {}
    # 传入异常类型Exception,捕获异常信息
    with pytest.raises(Exception) as exc_info:
        check()
    # 断言异常消息正确
    assert exc_info.value.args[0] == 'Positive vibes only'

更优雅的写法:把someMap改成函数参数

如果能修改原函数,把someMap作为参数传入,测试会更简洁且不需要依赖全局变量:

import pytest

# 修改后的原函数
def check(some_map):
    if 'connector' in some_map:
        print("proceed")
    else:
        raise Exception('Positive vibes only')
    return 1

# 测试正常分支
def test_check_with_connector():
    assert check({'connector': 'test'}) == 1

# 测试异常分支
def test_check_without_connector():
    with pytest.raises(Exception) as exc_info:
        check({})
    # 也可以用str()直接转异常对象获取消息
    assert str(exc_info.value) == 'Positive vibes only'

关键知识点回顾

  • pytest.raises()的正确用法是传入要捕获的异常类,比如Exception、ValueError等,而不是异常消息。
  • 捕获异常后,通过exc_info.value可以拿到抛出的异常对象,用.args[0]或者str()来获取异常消息进行断言。
  • 测试时要尽量隔离外部依赖,比如把全局变量改成函数参数,或者用monkeypatch工具修改全局变量(适合无法修改原函数的场景)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 17:40:17