ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

pytest 8.4.0 版本详解:RaisesGroup 异常组断言、收集控制与破坏性变更全解读

pytest 8.4.0 版本详解:RaisesGroup 异常组断言、收集控制与破坏性变更全解读 pytest 8.4.0 版本详解RaisesGroup 异常组断言、收集控制与破坏性变更全解读【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytestpytest 8.4.0 于 2025-06-02 正式发布是本仓库当前版本线中的一个重要里程碑它正式支持 Python 3.14、引入用于断言ExceptionGroup的pytest.RaisesGroup/pytest.RaisesExc、新增--force-short-summary、--disable-plugin-autoload、--stepwise-reset等命令行能力同时移除对 Python 3.8 的支持。阅读本文后你将掌握 8.4.0 的全部新特性、破坏性变更的迁移要点以及这些功能在当前仓库中的源码级实现位置可直接对照升级与使用。版本总览与升级方式pytest 8.4.0 是 8.x 系列中的功能型次版本按照语义化版本规范major.minor.patch见 doc/en/changelog.rst破坏性变更仅会在主版本中引入因此 8.4.0 中的移除与破坏性变更属于提前预告的清理动作。官方发布公告见 doc/en/announce/release-8.4.0.rst完整变更明细记录在 doc/en/changelog.rst。从 PyPI 升级到最新版本只需一条命令pip install -U pytest该版本包含新特性、既有功能改进与大量 bug 修复累计收到 60 余位贡献者的提交。发布后多个第三方插件如 pytest-redis、pytest-elasticsearch、pytest-dynamodb、pytest-mcp 等在 doc/en/reference/plugin_list.rst 中标注了pytest8.4.0的版本要求说明本次发布成为社区插件基线升级的重要节点。移除与破坏性变更升级前必须注意的四点8.4.0 的破坏性变更集中在四个方面升级后部分曾经只是警告的行为会直接变成失败或错误。异步测试不再警告后跳过此前若测试套件中存在异步测试但未安装任何合适的异步插件如 pytest-asyncio、pytest-trio、pytest-twisted、pytest-anyiopytest 只会发出警告并跳过从 8.4.0 起这类异步测试将直接失败issue #11372。这是为了让异步测试没有正确运行这一状态被显式暴露出来而不是静默通过。测试函数返回值非 None 将直接失败测试函数若返回除None之外的任何值这通常是忘记加断言、误把函数体写成表达式的结果此前只会产生警告8.4.0 起直接判为失败issue #12346。这是把可疑的测试写法从软提示升级为硬性错误有助于尽早发现无效测试。放弃 Python 3.8随着 Python 3.8 于 2024-10-07 到达生命周期终点8.4.0 正式放弃对它的支持issue #12874。如需继续使用 pytest 8.3.x 及更早版本请保留 Python 3.8 环境8.4.0 起请使用 Python 3.9。测试函数中残留的 yield 语法直接报错在测试函数体内使用yield的写法旧式生成器测试自 pytest 4.0 起就已不再执行此前以预期失败 弃用警告的形式提示8.4.0 起直接产生显式错误issue #12960相关说明可参阅 doc/en/announce/../.. 系列的更早公告与 doc/en/historical-notes.rst 中的历史背景。弃用预告异步 fixture 的解析约定8.4.0 对同步测试请求异步 fixture这一场景发出DeprecationWarningissue #10839。具体触发条件是请求一个异步 fixture但环境中没有任何提供pytest_fixture_setuphook 的实现来解析它。多数使用标准异步插件的用户不受影响但非标准 hook 配置或autouseTrue的用法需要留意。这为下一个主版本中的移除预留了缓冲期。新特性详解核心亮点pytest.RaisesGroup 与 pytest.RaisesExc8.4.0 最重要的功能是新增pytest.RaisesGroup用于断言ExceptionGroupPython 3.11 引入的异常组或通过exceptiongroup回填包使用其实现位于 src/_pytest/raises.py类文档明确标注.. versionadded:: 8.4。同时新增pytest.RaisesExcsrc/_pytest/raises.py它现在就是pytest.raises的底层实现逻辑也可作为RaisesGroup的参数来细化对子异常的匹配条件。相比pytest.raisesExceptionInfo.group_contains()RaisesGroup的匹配更严格所有指定异常必须出现且不允许出现任何多余异常。基本用法import pytest from pytest import RaisesGroup, RaisesExc def test_basic_group(): with RaisesGroup(ValueError): raise ExceptionGroup(, (ValueError(),)) def test_multiple_and_match(): with RaisesGroup( ValueError, ValueError, RaisesExc(TypeError, match^expected int$), match^my group$, ): raise ExceptionGroup( my group, [ValueError(), TypeError(expected int), ValueError()], ) def test_nested_groups(): with RaisesGroup(RaisesGroup(ValueError)): raise ExceptionGroup(, (ExceptionGroup(, (ValueError(),)),))关键参数说明均可从 src/_pytest/raises.py 的 docstring 确认match正则表达式作用于异常组及其__notes__PEP 678的字符串表示匹配前会去掉 repr 中 (5 subgroups)之类的分组计数后缀。check回调函数接收整个异常组返回True才算匹配成功。allow_unwrappedTrue当只期望单个异常/RaisesExc时允许该异常不包裹在异常组中直接抛出与match、check或多异常期望共用会报错。flatten_subgroupsTrue先把嵌套组内的所有异常拍平再匹配适合模拟except*的行为。匹配不区分异常顺序RaisesGroup(ValueError, TypeError)与RaisesGroup(TypeError, ValueError)等价。RaisesExc的三个匹配维度——异常类型、match正则、check回调——至少需要指定其一src/_pytest/raises.py 会校验三参皆空则抛ValueError。RaisesExc(ValueError).matches(exc)还可以独立用于逐个检查多个异常的场景。仓库对应的类型检查与测试样例见 testing/typing_raises_group.py 与 testing/python/raises_group.py。围绕raises系功能的配套增强还包括pytest.mark.xfail的raises参数现在可以接收pytest.RaisesGroup期望异常组时也可以传pytest.RaisesExc以使用check参数issue #12504。pytest.raises现在支持泛型写法pytest.raises(ExceptionGroup[Exception])以保留ExceptionInfo的完整类型标注issue #13115。传入空字符串给match会触发警告因为空正则匹配一切若想断言异常没有任何消息应使用match^$issue #13192。新增checkfn参数fn接收被捕获的异常并返回布尔值True视为匹配、False则重新抛出异常issue #13192。源码中check的 repr 与处理逻辑见 src/_pytest/raises.py。当match是^...$包裹的转义字符串且匹配失败时会输出可读的字符串 diff方便定位差异issue #13192。capteesys fixture捕获的同时透传输出新增capteesysfixtureissue #12081其实现位于 src/_pytest/capture.py它像capsys一样捕获 stdout/stderr同时会把输出继续传递给--capture指定的下一个处理器。适用于既需要断言输出内容、又希望输出正常流向日志/终端的场景def test_output(capteesys): print(hello) captured capteesys.readouterr() assert captured.out hello\n # 同时输出仍被透传到下一级处理器--force-short-summary强制紧凑摘要新增--force-short-summary选项issue #12713CLI 定义见 src/_pytest/terminal.py无论当前 verbosity 级别多高都强制使用精简摘要输出失败信息。这在 CI 日志、任务输出中快速定位失败尤其有用——当非紧凑输出非常冗长时仍然能看到一行行的失败摘要。collect_imported_tests控制跨文件收集pytest 传统上会收集测试模块命名空间中从其他文件 import 进来的类与函数。例如在tests/test_testament.py中from domain import Testament由于Testament以Test开头默认情况下它会被当作测试类收集。8.4.0 新增配置项collect_imported_testsissue #12749ini 注册见 src/_pytest/main.py收集逻辑见 src/_pytest/python.py设为其默认值true之外的false时pytest 只收集定义在本文件内的测试类/函数# pytest.ini [pytest] collect_imported_tests false# contents of tests/test_testament.py from domain import Testament # 不会再被收集 def test_testament(): ... # 仍会被收集配套测试见 testing/test_collect_imported_tests.py。断言截断阈值可配置新增truncation_limit_lines与truncation_limit_chars两个配置项issue #12765用于控制断言失败信息中代码片段与差异的截断阈值。其实现位于 src/_pytest/assertion/truncate.pymax_lines/max_chars直接读自这两个 ini 项并在 src/_pytest/assertion/init.py 注册[pytest] truncation_limit_lines 30 truncation_limit_chars 800console_output_style 支持 timesconsole_output_style新增times取值issue #13125可在每条测试结果后展示其执行耗时适合做性能摸底pytest --console-output-styletimes--disable-plugin-autoload替代环境变量的命令行开关此前要禁用插件自动加载需设置PYTEST_DISABLE_PLUGIN_AUTOLOAD环境变量8.4.0 新增等价的--disable-plugin-autoload标志issue #13253见 src/_pytest/helpconfig.py并且由于它可以写进addopts现在还能在配置文件中统一控制[pytest] addopts --disable-plugin-autoload隐藏参数集id 中不显示参数hidden-param占位符\0此前用于隐藏参数集现在可直接用在pytest.param的id或Metafunc.parametrize的ids中issue #13228隐藏该参数集在测试名中的显示。既有功能改进PEP 657 追踪traceback 显示精确表达式位置short与long两种 traceback 风格现在获得部分 PEP 657 支持issue #10224能够像 Python 3.11 的调试体验一样用^精确标出出错的那段表达式test_tracebacks.py:12: in test_gets_correct_tracebacks assert manhattan_distance(p1, p2) 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^ test_tracebacks.py:6: in manhattan_distance return abs(point_1.x - point_2.x) abs(point_1.y - point_2.y) ^^^^^^^^^ E AttributeError: NoneType object has no attribute xpythonpath 更早生效pythonpath配置项现在会在初始化更早的阶段写入$PYTHONPATHissue #11118因此也影响通过-p选项加载的插件——自定义插件若要依赖测试目录下的模块这一改动直接解决了加载顺序问题。parser.addini 支持 int/float 类型插件作者在pytest_addoption中调用parser.addini时type参数新增int与float支持issue #11381让配置文件中的数值自动完成类型解析def pytest_addoption(parser): parser.addini(int_value, typeint, default2, helpmy int value) parser.addini(float_value, typefloat, default4.2, helpmy float value)[pytest] int_value 3 float_value 5.4fixture 显示为 fixture object测试输出中 fixture 现在以明确的 fixture object 形式呈现而不是普通的函数对象issue #11525初学者更容易发现在同一模块声明了 fixture 却忘了在测试函数参数中请求它这类错误。其他值得关注的改进JUnit XML根标签testsuites新增固定值属性namepytest testsissue #12736符合 junit-10.xsd 规范schema 见 testing/junit-10.xsd。unraisable 与 thread exception 全面增强issue #12958 / #13016尽早挂载 hook、在卸载前调用 GC、每个测试阶段收集多条异常、报告tracemalloc分配回溯、避免基于生成器的 hook 以正确处理StopIteration、把未处理异常作为警告的 cause并在 hook 内即时计算repr防止对象被复活导致信息失真。pytest.approx 改进支持数字与非数字混合的集合比较issue #13010修复bool与numpy.bool_的相等性issue #130478.3.4/8.3.5 引入的回归repr在 0.0011000 区间内以十进制而非科学计数法展示容差如42 ± 1issue #6985并补充说明approx认为布尔值与数字 0/1 不相等issue #13218。实现入口见 src/_pytest/approx.py。stepwise 模式重大改进issue #13122实现见 src/_pytest/stepwise.py不再忘记上次失败的测试——即使后续直接运行不带--stepwise的隔离测试再次--stepwise时也会从上次失败处继续测试套件变化当前按测试数量判断会自动重置内部状态新增--stepwise-reset/--sw-reset显式清空状态重启工作流。Python 3.14 官方支持issue #13308。异常组 traceback 过滤过滤ExceptionGroup回溯时排除 pytest 内部帧issue #13380。收集性能优化优化FSCollector的路径解析并给nodes._check_initialpaths_for_relpath加lru_cacheissue #13420。错误信息更友好重复参数化错误不再展示内部堆栈issue #13457空usefixtures标记发出警告issue #12426在pytest.param上使用usefixtures由静默无效改为报错issue #4112断言重写警告信息中的:改为;以便用标准 warning 过滤器处理issue #5473。输出渲染pygments由可选依赖变为必选依赖输出始终带源码高亮可用--code-highlightno关闭issue #7683。PdbPython 3.13 下可以在 Pdb 中导航异常链issue #12707。值得关注的 bug 修复要点--durations-min在-vv下不再失效issue #12938。测试、setup、teardown 中抛出的StopIteration得到正确处理issue #12929。修复pytest.mark.parametrize等标记位于staticmethod/classmethod之上时未被应用的问题issue #12863。Metafunc.parametrize在indirectTrue时传scope不再破坏其他 fixture 对参数化 fixture 的依赖issue #13248。修复支持位置只读self/ 关键字只读 fixture 参数的方法定义如def test_method(self, /, *, fixture): ...issue #13377。修复 pytest 可能报告负耗时的异常issue #13384。修复 PyPy 上收集高阶作用域参数时可能的KeyError崩溃issue #13312。Config.add_cleanup回调抛异常不再阻断后续 cleanupissue #12981。filterwarnings 的应用与撤销时机提前/延后使警告即错误能覆盖整个运行过程包括卸载 unraisable/threadexcept hook 之前issue #10404。打包与下游说明明确指定colorama、iniconfig、packaging的最低允许版本并将python_version3.11下exceptiongroup的最低版本从 RC 提升为正式版issue #13317。pytest.TerminalReporter被纳入公开 API因为它是pytest_terminal_summaryhook 签名的一部分issue #6649文档见 doc/en/reference/reference.rst。--help输出中的 CLI 选项分组得到整理issue #13221。如何在当前仓库验证与深入阅读本文所依据的完整变更记录位于 doc/en/changelog.rstpytest 8.4.0 章节发布公告见 doc/en/announce/release-8.4.0.rst。若想深入源码异常组断言实现src/_pytest/raises.pyRaisesGroup与 src/_pytest/raises.pyRaisesExc测试见 testing/python/raises_group.pystepwise 状态管理与重置src/_pytest/stepwise.py输出捕获透传src/_pytest/capture.py收集控制与截断配置src/_pytest/python.py、src/_pytest/assertion/truncate.py插件自动加载开关src/_pytest/helpconfig.py。升级到 8.4.0 后建议优先自查四类破坏性变更异步测试、非 None 返回值、Python 3.8、函数内 yield再逐步引入RaisesGroup与--force-short-summary等新能力即可平稳完成本次版本迁移。【免费下载链接】pytestThe pytest framework makes it easy to write small tests, yet scales to support complex functional testing项目地址: https://gitcode.com/GitHub_Trending/py/pytest创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表