从版本3.1开始,pytest现在在测试执行期间自动捕获警告并在会话结束时显示它们

运行代码会输出

一.控制警告

类似于Python的警告过滤器和-W标志,pytest提供了直接的-W标志来控制哪些警告被忽略,显示或转换为错误

以下示例展示了如何将任何UserWarning类别的警告视为错误

相同的选项可以使用filterwarnings ini选项在pytest.ini或pyproject.toml文件中设置

以下配置将忽略所有用户警告和匹配正则表达式的特定弃用警告,但会将所有其他警告转换为错误

当一个警告与列表中多个选项匹配时,执行最后一个匹配选项的操作

注:-w标志和filtetwarning ini选项使用结构相似的警告过滤器,但每个配置选项对其过滤器的解释方式不同,如filterwarnings中的*message*是一个字符串,包含警告开头必须匹配的正则表达式(不区分大小写),而-W中的*message*是一个字面字符串,警告消息的开头必须包含该字符串(不区分大小写),忽略消息开头或结尾的任何空白字符

1.@pytest.mark.filterwarnings

可以使用@pytest.mark.filterwarnings标记向特定的测试项添加警告过滤器,从而更精细地控制在测试、类甚至模块级别应捕获哪些警告

可以使用单独的装饰器指定多个过滤器

注:关于装饰器顺序和过滤器优先级,装饰器是按逆序评估的,因此必须与传统warnings.filterwarnings()和-W选项用法相反的顺序来列出警告过滤器,早期@pytest.mark.filterwarnings装饰器的过滤器优先于来自后续装饰器的过滤器

通过标记应用的过滤器优先于通过命令行传递或由filtetwarnings ini选项配置的过滤器

可以使用filterwarnings标记作为类装饰器,或通过设置pytestmark变量,将过滤器应用于一个类的所有测试,或一个模块中的所有测试

2.禁用警告摘要

不推荐,可以使用--disable-warnings命令行选项来完全禁止测试运行输出中的警告摘要

二.完全禁用警告捕获

此插件默认启用,可以在pytest.ini文件中通过以下方式完全禁用

或者在命令行中传递 -p no:warnings,可以在测试套件使用外部系统处理警告

三.DeprecationWarning和PendingDeprecationWarning

根据PEP 565的建议,pytest默认会显示用户代码和第三方库中的DeprecationWarning和PendingDeprecationWarning警告,这有助于用户保持其代码的现代化,并避免在弃用警告实际移除时出现故障

用户通过pytest.warns()、pytest.deprecated_call()或使用recwarn fixture捕获任何类型的警告的特定情况下,将完全不显示任何警告

隐藏在无法控制的代码(如第三方库)中发生的某些特定弃用警告很有用,在这种情况下,可以使用警告过滤器选项(ini或标记)来忽略这些警告

这将忽略所有类型为DeprecationWarning的警告,其中消息的开头与正则表达式“.*U.*mode is deprecated”匹配

注:如果使用PYTHONWARNINGS环境变量或-W命令行选项在解释器级别配置警告,pytest默认将不配置任何过滤器

此外,pytest不遵循PEP 565中重置所有警告过滤器的建议,可能会破坏通过调用warnings.simplefilter()自行配置警告过滤器的测试套件

四.确保代码触发弃用警告

可以使用pytest.deprecated_call()检查特定函数调用是否触发DeprecationWarning或PendingDeprecationWarning

运行测试可以看到弃用警告

五.使用warns函数断言警告

可以使用pytest.warns()检查代码是否引发特定警告,其工作方式类似于raises(除了raises不捕获所有异常,只捕获expected_exception)

如果为引发相关警告,则测试将失败,使用关键字参数match来断言警告匹配文本或正则表达式,要匹配可能包含正则表达式元自动(如(或 . )的字面字符串,可以先使用re.escape对模式进行转义

可以对函数或代码字符串调用pytest.warns()

pytest.warns(expected_warning,func,*args,**kwargs)

pytest.warns(expected_warning,"func(*args,**kwargs)")

该函数还返回所有引发的警告列表(作为warnings.WarningMessage对象),可以查询这些警告以获取更多信息

可以使用recwarn fixture详细检查引发的警告

recwarn fixture会自动确保在测试解释时重置警告过滤器,因此不会泄露任何全局状态

六.记录警告

可以使用pytest.warns()上下文管理器或recwarn fixture记录引发的警告

要使用pytest.warns()记录警告而不对警告进行任何断言,请不传递任何参数作为预期的警告类型,它将默认为通用警告

recwarn fixture将记录整个函数的警告

recwarn fixture和pytest.warns()上下文管理器都返回相同的记录警告接口:一个WarningsRecorder实例,要查看记录的警告,可以迭代此实例,对其调用len以获取记录的警告数量或对其进行索引以获取特定的记录警告

七.测试中警告的其他用例

以下是一些在测试中经常出现的涉及警告的用例,以及如何处理它们的建议:

  • 要确保发出至少一个指示的警告,请使用
  • 要确保只发出某些警告,请使用
  • 要确保不发出任何警告,请使用
  • 要抑制警告,请使用

八.自定义失败消息

记录警告为在未发出警告或满足其他条件是生成自定义测试失败消息提供了机会如果在调用f时没有发出警告,则not record将评估为True,然后,可以使用自定义错误消息调用pytest.fail()

九.内部pytest警告

在某些情况下,例如不当使用或弃用功能,pytest可能会发生自己的警告

如果pytest遇到一个与python_classes匹配但同时定义了__init__构造函数的类,pytest将发出警告,因为这会阻止该类被实例化

这些警告可以使用与过滤其他类型警告相同的内置机制进行过滤

十.资源警告

如果启用tracemalloc模块,则当pytest捕获到ResourceWarning时,可以获得其来源的额外信息

在运行测试时启用teacemalloc的一种便捷方法是将PYTHONTRACEMOLLOC设置为足够大的帧数(如:20.但该数字取决于应用程序)

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐