如何为抛出含字符串信息的异常编写pytest测试用例?
如何正确编写pytest测试用例捕获自定义异常?
你的测试代码里有几个关键问题,导致PyCharm报错且测试逻辑不正确,我来一步步帮你修正:
先明确错误根源
pytest.raises()参数类型错误:你传了字符串e给它,但这个方法需要的是异常类型(比如Exception)或者异常类型的元组,不是异常消息字符串——这就是PyCharm提示类型不匹配的核心原因。- 异常捕获后的断言逻辑错误:当
check()抛出异常时,函数不会返回任何值,res根本不会被赋值,所以assert res == e这行代码永远不会执行,反而会导致测试失败。 - 未控制依赖变量
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
相关产品推荐
相关产品推荐

