pytest调用str()转换错误类型对象导致异常文本精确匹配失败问题
pytest 异常信息精确匹配问题说明
问题场景
当需要校验Python异常返回的精确文本时,直接通过str()转换捕获到的异常实例、再和预期字符串比对的写法会出现匹配失败的问题,影响错误场景的测试准确性。
复现代码如下:
异常抛出逻辑
def erroring_func(name, required_item_list): # 省略业务逻辑,直接抛出KeyError raise KeyError(f'{name} is missing required item(s): {required_item_list}')
错误的测试用例写法
def test_erroring_func(): with pytest.raises(KeyError) as err: name = 'This dataframe' required_item_list = ['a column'] _ = erroring_func(name, required_item_list) assert str(err.value) == f"{name} is missing required item(s): {required_item_list}"
报错现象
上述代码运行后会抛出如下断言错误:
assert '"This dataframe is missing required item(s): [\'lat\']"' == "This dataframe is missing required item(s): ['lat']
根因分析
该问题是KeyError这类异常的字符串转换逻辑特殊导致的:str(err.value)的输出会自动给原异常信息额外包裹双引号,同时对内部的单引号添加转义反斜杠,这类转义内容无法通过普通f-string生成完全匹配的内容,也无法在字符串创建后手动插入等效的转义效果。
解决方案
有两种通用的修复方案可解决该匹配问题:
- 读取异常的
args属性第一个元素做比对,避免直接对异常实例做str()转换
将断言语句修改为:assert err.value.args[0] == f"{name} is missing required item(s): {required_item_list}" - 使用pytest内置的
match参数做正则匹配,省略手动比对步骤
测试用例可简化为:def test_erroring_func(): name = 'This dataframe' required_item_list = ['a column'] expected_msg = f"{name} is missing required item(s): {required_item_list}" with pytest.raises(KeyError, match=expected_msg): erroring_func(name, required_item_list)
内容的提问来源于stack exchange,提问作者Mark_Anderson
相关产品推荐
相关产品推荐

