Pytest 5.x+ 升级指南:通过自定义标记实现命令行条件测试运行与跳过

Pytest 5.x+ 升级指南:通过自定义标记实现命令行条件测试运行与跳过

本文旨在解决 pytest 从 4.x 升级到 5.x+ 后,`pytest.config` 被移除导致无法通过命令行标志条件运行或跳过特定测试的问题。我们将介绍如何利用 pytest 5.x+ 及更高版本中的自定义标记(`pytest.mark`)与 `-m` 命令行选项,优雅地实现对带有特定装饰器的测试进行灵活的选择性执行,从而避免大规模代码修改。此方法不仅保持了代码的简洁性,也提升了测试管理的效率和灵活性。

在 Pytest 4.x 版本中,开发者通常会利用 pytest.config.getoption 方法结合自定义装饰器来根据命令行参数动态控制特定测试的运行或跳过。例如,以下代码展示了如何定义一个 integration 装饰器,使其在 –integration 命令行标志不存在时自动跳过集成测试:

# common.py (Pytest 4.x 示例)import pytestintegration = pytest.mark.skipif(    not pytest.config.getoption('--integration', False),    reason="Integration tests require --integration flag")

然后,在测试文件中,这些装饰器可以被方便地应用于相关测试函数:

# test_something.py (Pytest 4.x 示例)from .common import integration@integrationdef test_mytest():    assert 1 == 1@integrationdef test_other_mytest():    assert 2 == 2

然而,从 Pytest 5.x+ 版本开始,pytest.config 属性已被移除,导致上述代码在运行时会抛出 AttributeError: module ‘pytest’ has no attribute ‘config’ 错误。对于那些拥有大量使用此类装饰器的现有测试的项目来说,如何在不进行大规模代码重构的前提下,在 Pytest 5.x+ 中实现相同的灵活性,成为了一个亟待解决的问题。

Pytest 5.x+ 的解决方案:利用自定义标记与 -m 选项

Pytest 5.x+ 提供了一种更简洁、更标准化的方式来解决这个问题,即通过自定义标记(Custom Markers)与内置的 -m 命令行选项。这种方法不仅能够实现与旧版 pytest.config 相同的功能,而且更加符合 Pytest 的设计哲学,并且对现有测试代码的改动极小。

步骤一:定义并应用自定义标记

首先,我们需要重新定义 integration 装饰器。在 Pytest 5.x+ 中,我们不再需要 pytest.config 来检查命令行选项,而是直接使用 pytest.mark 来创建标记。

# common.py (Pytest 5.x+ 解决方案)import pytest# 直接定义一个名为 'integration' 的标记integration = pytest.mark.integration

然后,在测试文件中,继续使用这个新的 integration 装饰器来标记需要特殊处理的测试:

# test_skip.py (Pytest 5.x+ 解决方案)from .common import integration@integrationdef test1():    assert Truedef test2(): # 未被标记的测试    assert True

步骤二:注册标记到 pytest.ini

为了让 Pytest 识别我们自定义的 integration 标记,并避免产生 PytestUnknownMarkWarning 警告,我们需要在项目根目录下的 pytest.ini 配置文件中注册它。

# pytest.ini[pytest]markers =  integration: marks tests as integration tests (deselect with '-m "not integration"')

在 markers 部分,每行定义一个标记,冒号后可以添加对该标记的简短描述,这对于团队协作和文档化非常有帮助。

步骤三:通过命令行参数控制测试执行

完成上述配置后,我们就可以利用 Pytest 的 -m 命令行选项来灵活地运行或跳过带有特定标记的测试了。

运行所有测试

不带任何标记筛选参数时,Pytest 将运行所有收集到的测试:

$ pytest -v========================================= test session starts =========================================platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3cachedir: .pytest_cacherootdir: /home/lars/tmp/python, configfile: pytest.inicollected 2 itemstest_skip.py::test1 PASSED                                                                      [ 50%]test_skip.py::test2 PASSED                                                                      [100%]========================================== 2 passed in 0.00s ==========================================

只运行带有 integration 标记的测试

使用 -m integration 选项,Pytest 将只选择并运行被 @integration 装饰器标记的测试:

$ pytest -v -m integration========================================= test session starts =========================================platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3cachedir: .pytest_cacherootdir: /home/lars/tmp/python, configfile: pytest.inicollected 2 items / 1 deselected / 1 selectedtest_skip.py::test1 PASSED                                                                      [100%]=================================== 1 passed, 1 deselected in 0.00s ===================================

只运行不带 integration 标记的测试

使用 -m ‘not integration’ 选项,可以运行所有未被 integration 标记的测试。注意 not integration 表达式需要用引号括起来,以避免 shell 解析问题。

$ pytest -v -m 'not integration'========================================= test session starts =========================================platform linux -- Python 3.11.6, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3cachedir: .pytest_cacherootdir: /home/lars/tmp/python, configfile: pytest.inicollected 2 items / 1 deselected / 1 selectedtest_skip.py::test2 PASSED                                                                      [100%]=================================== 1 passed, 1 deselected in 0.00s ===================================

注意事项与最佳实践

标记注册的重要性:务必在 pytest.ini 中注册所有自定义标记。未注册的标记虽然可以使用,但 Pytest 会发出警告,提示该标记未知。这有助于保持测试代码的清晰性和可维护性。-m 选项的强大功能:-m 选项支持复杂的布尔表达式,例如 pytest -m “integration and slow” 或 pytest -m “not (integration or ui)”,这使得测试选择异常灵活。平滑过渡:这种方法最大的优势在于其对现有测试代码的侵入性极小。对于从 Pytest 4.x 升级的项目,只需要修改定义自定义装饰器的文件(如 common.py),将 pytest.mark.skipif(not pytest.config.getoption(…)) 替换为简单的 pytest.mark.your_marker_name,而无需修改所有已使用该装饰器的测试函数。清晰的意图:使用 pytest.mark 明确地标记测试的属性,使得测试的意图更加清晰,也方便了团队成员理解和管理测试集。

总结

从 Pytest 4.x 升级到 5.x+ 并解决 pytest.config 移除带来的条件测试执行问题,最优雅且推荐的方式是采用自定义标记结合 -m 命令行选项。通过简单的两步:重新定义装饰器为 pytest.mark.your_marker 并在 pytest.ini 中注册该标记,即可实现对测试的精细化控制。这种方法不仅解决了兼容性问题,还提升了测试管理的灵活性和可维护性,是 Pytest 升级过程中的一项重要实践。

以上就是Pytest 5.x+ 升级指南:通过自定义标记实现命令行条件测试运行与跳过的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1377411.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月14日 17:45:16
下一篇 2025年12月14日 17:45:23

相关推荐

  • 解决arm64架构下SpaCy日语模型(ja_core_news_sm)安装问题

    本文旨在解决在arm64架构(如M1/M2 Mac)的Docker容器中,安装SpaCy日语模型`ja_core_news_sm`时遇到的`sudachipy`编译错误。该错误通常由于缺少Rust编译器引起。本文将提供详细的安装步骤,包括安装Rust编译器、更新pip和`sudachipy`,以及安…

    2025年12月14日
    000
  • Pandas数据清洗:按ID标准化标签的策略与实现

    本文探讨了如何使用Pandas在数据集中对每个唯一ID的标签进行标准化。核心策略是识别每个ID最常见的标签作为标准,若无明确多数,则默认取一个稳定值。文章将详细介绍多种Pandas实现方法,包括利用`groupby().transform()`和`mode()`的简洁方案,以及更高效的`value_…

    2025年12月14日
    000
  • Pytest 5.x+ 迁移:使用自定义标记实现条件测试执行

    pytest 5.x+ 版本移除了 `pytest.config`,导致旧版中通过命令行参数控制测试跳过/运行的方法失效。本文将指导用户如何优雅地将现有基于装饰器的条件测试逻辑迁移到 pytest 5.x+,通过利用自定义标记(`pytest.mark`)和 `pytest.ini` 配置,结合 `…

    2025年12月14日
    000
  • KeyBERT安装指南:解决Rust/Cargo依赖引发的安装错误

    本教程旨在解决使用`pip install keybert`时常见的安装失败问题,特别是当出现rust/cargo未安装的错误提示时。我们将详细介绍如何正确安装rust及其包管理器cargo,这是keybert及其某些底层组件编译所必需的。通过遵循本指南,用户将能够顺利完成keybert的安装,并开…

    2025年12月14日
    000
  • 使用Python求解矩阵微分方程组

    本文档旨在指导读者使用Python解决矩阵微分方程组。我们将详细介绍如何使用scipy.integrate库中的odeint函数,并处理矩阵运算中的维度问题,最终得到所需的解并进行可视化。本文档通过一个实际案例,展示了从问题建模到代码实现的完整流程,帮助读者掌握使用Python解决此类问题的核心技巧…

    2025年12月14日
    000
  • python如何解决初始化执行次数

    初始化执行多次通常因对象重复创建或继承调用不当。1. 避免频繁实例化,复用对象可减少__init__调用;2. 使用单例模式通过__new__控制实例唯一性,并用标记确保__init__仅执行一次;3. 多重继承中应正确使用super(),依赖MRO机制避免父类__init__被重复调用;4. 可采…

    2025年12月14日
    000
  • AWS CDK Python Lambda层部署:避免导入错误的路径配置指南

    本文旨在解决使用aws cdk部署python lambda层时常见的导入错误问题。核心内容聚焦于资产路径配置的常见陷阱,即错误地将`_lambda.code.from_asset()`指向包含压缩包的目录而非压缩包本身。文章将通过示例代码阐明正确配置方法,并提供一系列故障排除和最佳实践建议,确保l…

    2025年12月14日
    000
  • 在 Python 中无需等待即可启动或恢复异步方法/协程

    本文旨在解决在 python 中启动异步协程时遇到的困惑,并提供一种在不阻塞主线程的情况下,类似 javascript 的方式立即执行异步任务的方案。文章深入探讨了 `asyncio` 库的特性,并结合 `run_coroutine_threadsafe` 方法展示了如何在独立的事件循环中运行协程,…

    2025年12月14日
    000
  • Python函数参数传递:从值到键的转换策略

    本文旨在解决python函数中一个常见的参数传递误区:当函数需要引用字典的键(如资源名称)时,却错误地接收了键对应的数值,导致尝试对非字典类型使用`.key()`方法而引发`attributeerror`。教程将通过重构函数参数,演示如何直接传递键名,从而在函数内部通过键访问字典值,并确保在输出中正…

    2025年12月14日
    000
  • 在Python中以类似JavaScript的方式启动异步协程

    本文旨在解决python异步编程中协程启动方式与javascript等语言的差异。通过asyncio.run_coroutine_threadsafe方法,我们可以在独立的事件循环中运行协程,并提供了一个attempt函数来检测协程的完成状态,从而实现更灵活的异步任务管理,避免阻塞主线程。 在Pyt…

    2025年12月14日
    000
  • python如何使用skimage包提取图像

    使用skimage可便捷实现图像读取、颜色转换与特征提取:先用io.imread读取图像,通过color.rgb2gray转灰度图,再利用feature.canny进行边缘检测,filters.threshold_otsu实现阈值分割,结合numpy统计像素均值与标准差,最终用io.imsave保存…

    2025年12月14日
    000
  • Python数据清洗:利用正则表达式精确移除文本中的特定分隔符行

    本教程探讨了在python中处理包含结构化分隔符的文本数据时遇到的常见挑战。当分隔符与数据本身包含相同字符(如连字符)时,简单的字符串替换方法会误删有效数据。文章将详细介绍如何利用正则表达式re.fullmatch精确识别并移除仅由特定字符组成的分隔符行,同时保留数据中的连字符,从而实现高效且准确的…

    2025年12月14日
    000
  • Python类属性如何使用

    类属性属于类本身并被所有实例共享,可用于存储公共数据或状态。定义在类中方法外,通过类名访问,修改后影响所有实例(除非实例定义同名属性遮蔽)。适用于常量、计数等场景,但应避免将可变对象作为类属性,以防意外共享导致数据污染。 Python中的类属性是定义在类中、方法之外的变量,它们属于类本身,而不是某个…

    2025年12月14日
    000
  • Pytest 5.x+ 升级:利用自定义标记和命令行参数高效管理测试执行

    本文旨在解决 pytest 5.x+ 版本中 `pytest.config` 移除后,如何通过命令行参数控制特定装饰器标记的测试运行或跳过的问题。我们将介绍一种优雅的解决方案,即利用 pytest 的自定义标记(custom markers)功能结合 `-m` 命令行选项,实现对测试执行流程的精细化…

    2025年12月14日
    000
  • Pandas DataFrame到多层嵌套字典的转换技巧

    本文详细介绍了如何利用pandas库将表格数据(dataframe)高效转换为多层嵌套字典。通过使用`pd.dataframe.pivot`方法,结合`to_dict()`,可以轻松实现以特定列作为外部键和内部键,并以另一列作为值的数据结构,从而满足快速按层级访问数据的需求。文章提供了具体代码示例,…

    2025年12月14日
    000
  • 如何将 Iris 数据集加载到 Pandas DataFrame 中

    本文将介绍如何使用 scikit-learn 库加载 Iris 数据集,并将其转换为 Pandas DataFrame。我们将展示如何查看 DataFrame 的信息,以及如何使用 `describe()` 方法获取数据集的描述性统计信息。此外,还将介绍两种在 Jupyter Notebook 或类…

    2025年12月14日
    000
  • AWS CDK Python Lambda层部署:解决导入错误的关键路径配置

    在使用aws cdk python部署lambda层时,开发者可能会遇到导入错误,即使相同的层zip包手动上传至控制台能正常工作。本教程旨在解决一个常见误区:`_lambda.code.from_asset()`方法需要精确指向lambda层的`.zip`文件路径,而非其所在目录。理解并正确配置资产…

    2025年12月14日
    000
  • 获取Python顶层代码对象的技巧与实践

    本文深入探讨了在python中获取模块顶层代码对象的方法。由于顶层代码的执行机制与函数不同,其代码对象不直接暴露。我们将介绍如何利用`inspect`模块遍历调用栈,定位到顶层帧,进而提取其对应的代码对象,并分析其`co_consts`等属性,为理解python运行时机制提供实用工具。 在Pytho…

    2025年12月14日
    000
  • Quart框架中SQLite连接的线程安全关闭机制

    本文探讨了在quart框架中使用`teardown_appcontext`关闭sqlite数据库连接时遇到的线程错误,即`sqlite3.programmingerror: sqlite objects created in a thread can only be used in that sam…

    2025年12月14日
    000
  • 使用 python-pptx 控制 PPTX 幻灯片标题字体大小

    本文旨在解决在使用 python-pptx 库生成 PPTX 文件时,如何控制幻灯片标题字体大小的问题。通过分析常见错误和提供正确的代码示例,本文将指导您如何有效地修改幻灯片标题的字体大小,从而生成更符合需求的演示文稿。本文重点在于理解 `TextFrame` 和 `Run` 对象在 python-…

    2025年12月14日
    000

发表回复

登录后才能评论
关注微信