Python的pytest框架(5)--测试标记(Markers)

2024-04-22 15:52

本文主要是介绍Python的pytest框架(5)--测试标记(Markers),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

该篇将循序渐进地详细拆解 pytest.mark 装饰器:

目录

一、概念

二、标记的基本结构与使用

三、标记在测试中的层次应用

四、标记的筛选与运行

五、标记与测试行为控制

六、标记与测试参数化

七、标记的注册与自定义

1、通过pytest.ini配置文件:

2、通过conftest.py文件:

八、标记与第三方插件的集成


一、概念

在软件测试中,经常需要对大量的测试用例进行分类、筛选和管理。为了提高测试的组织性和可维护性,pytest 提供了一种称为“标记”(Marker)的功能。标记是一种元数据,允许我们为测试函数、类或模块添加额外的描述性信息。这些信息可以帮助我们:

  • 分类测试:根据测试的目的、重要性、阶段(如单元测试、集成测试、冒烟测试等)对测试进行分组。
  • 筛选测试:在运行测试时,通过标记快速选择特定类型的测试进行执行,避免运行全部测试。
  • 控制测试行为:标记可以指示 pytest 对特定测试采取特定的操作,如跳过、预期失败等。
  • 集成第三方工具:标记可与某些 pytest 插件或外部工具配合,提供更丰富的测试报告、自动化处理等。

二、标记的基本结构与使用

标记是通过 pytest.mark 装饰器来应用的。装饰器是一种 Python 语法,用于修改或增强函数、类等对象的行为。在 pytest 中,使用 pytest.mark.<marker_name> 形式的装饰器为测试项添加标记。实例如下:

import pytest# 使用 @pytest.mark.smoke 标记一个冒烟测试
@pytest.mark.smoke
def test_login():...# 使用 @pytest.mark.integration 标记一个集成测试
@pytest.mark.integration
class TestPaymentSystem:...

pytest 内置了一些常见的标记名称,这些标记可以直接在测试代码中使用,以下是一些常见的内置标记名称及其用途:

标记名称含义与用途分类
smoke冒烟测试,快速验证核心功能是否正常
测试类型或阶段
regression回归测试,检查已有功能在代码变更后是否正常,防止引入新的 bug
unit单元测试,针对代码最小可测试单元进行隔离测试
integration集成测试,验证不同模块或组件间的交互是否正确
system系统测试,测试整个系统作为一个整体的功能和行为
e2e / end-to-end端到端测试,模拟用户操作验证完整业务流程的正确性
slow耗时较长的测试,可以用于筛选并单独运行这类测试,或者在持续集成(CI)环境中跳过它们以加快测试周转时间。执行条件
fast快速测试,用于快速验证关键功能或优先运行
flaky易变或不可靠的测试,可能间歇性失败,标记为 flaky 的测试在失败时可以被报告为预期失败(xfail),不影响整体测试结果。
network需要网络连接的测试资源要求或限制
database依赖数据库的测试
live_server需要与实际运行服务器交互的测试
no_cover不计入代码覆盖率统计的测试
windows / linux / macos只能在特定操作系统上运行的测试特定环境或条件
python_version依赖特定 Python 版本的测试
requires_gpu需要 GPU 支持的测试
requires_redis / requires_mysql依赖特定第三方服务或软件的测试

三、标记在测试中的层次应用

标记可以应用在不同测试层次上,影响范围从单个测试函数到整个测试模块。

  • 函数级标记:直接应用于测试函数,仅对该函数生效。
  • 类级标记:应用于测试类,类中所有测试函数都将继承该标记。
  • 模块级标记:在 conftest.py 或测试模块顶部使用 pytestmark = pytest.mark.<marker_name>,标记整个模块内的所有测试。

实例如下:

# 函数级标记
@pytest.mark.unit
def test_unit():...# 类级标记
@pytest.mark.integration
class TestIntegration:def test_large_query(self):...def test_concurrency(self):...# 模块级标记(在 conftest.py 或测试模块顶部)
pytestmark = pytest.mark.regression

四、标记的筛选与运行

在运行 pytest 命令时,可以通过 -m(或 --mark)选项指定一个标记表达式来筛选测试。标记表达式可以包含标记名称、逻辑运算符(and、or、not)以及括号用于分组。示例:

# 执行所有标记为 smoke 的测试
pytest -m smoke# 执行标记为 smoke 或 integration 的测试
pytest -m "smoke or integration"# 执行既非 slow 也非 integration 的测试
pytest -m "not slow and not integration"# 运行同时带有 unit 和 integration 的测试
pytest -m "unit and integration"# 复杂组合筛选
pytest -m "(system or integration) and not unit"  #运行system或integration,且不运行带有unit的测试

在项目的 pytest.ini 配置文件中,可以设置 addopts 键来指定默认的标记筛选规则。例如:

[pytest]
addopts = -m "not slow and not flaky"

这样,除非在命令行中显式覆盖,否则 pytest 将默认排除标记为 slow 或 flaky 的测试。

pytest 的测试报告会显示每个测试用例的标记信息。当通过标记筛选运行测试时,报告会清晰地展示哪些测试因为标记筛选而被包含或排除。这对于理解测试执行情况和分析测试结果非常有帮助。在实际使用中,应结合项目特点和团队约定,合理使用标记和筛选功能,确保测试的有效性和覆盖率。

五、标记与测试行为控制

某些标记可以直接控制测试的执行行为,如跳过、预期失败等。

  • pytest.mark.skip:无条件跳过标记了该标记的测试。
  • pytest.mark.skipif:在给定条件为真时跳过测试,接受一个条件表达式和可选的跳过原因。
  • pytest.mark.xfail:预期测试失败,如果测试确实失败,则视为“预期失败”,否则为“意外通过”。接受条件表达式、预期失败原因、是否严格检查意外通过等参数。
  • pytest.mark.usefixtures:强制使用 fixtures,即使测试函数没有显式请求这些 fixtures,pytest 也会在测试执行前准备并清理它们。

实例如下:

import sys
import pytest# 无条件跳过测试
@pytest.mark.skip(reason="待修复")
def test_buggy_feature():...# 在 Python 版本低于 3.7 时跳过测试
@pytest.mark.skipif(sys.version_info < (3, 7), reason="Requires Python 3.7+")
def test_new_syntax():...# 预期测试失败,但允许意外通过
@pytest.mark.xfail(reason="Known issue with this combination")
def test_unstable_combination():...import os
#如果环境变量 RUN_DATABASE_TESTS 未设置或者其值为假(如空字符串或 "False"),该测试将被跳过。
@pytest.mark.skipif(not os.environ.get("RUN_DATABASE_TESTS"), reason="Database tests disabled")
def test_database_connection():# 连接并验证数据库连接# ...@pytest.fixture
def shared_resource():resource = create_shared_resource()yield resourcecleanup_shared_resource(resource)@pytest.mark.usefixtures("shared_resource")
class TestWithShared_resource:def test_case1(self):...def test_case2(self):...#这种方式也简化了代码,避免了在每个测试方法上重复添加装饰器。

六、标记与测试参数化

pytest.mark.parametrize 是一个特殊的标记,用于创建参数化的测试,即一个测试函数可以针对多组不同的输入数据执行多次。我在pytest专栏里已经写了关于参数化的文章:Python的pytest框架(4)--参数化测试

七、标记的注册与自定义

若要使用自定义标记,需要在 pytest.ini 或 conftest.py 中注册标记及其说明。自定义标记可以像内置标记一样使用,并可能与特定插件或内部逻辑交互。pytest提供了两种主要方式来注册自定义标记:

1、通过pytest.ini配置文件:

在项目根目录下创建或编辑pytest.ini文件,添加[pytest]节,并在其中定义标记。格式如下:

[pytest]
markers =slow: marks tests as slow (deselect with '-m "not slow"')requires_gpu: marks tests that require a GPU to runapi_integration: marks tests that involve API integration...

在这里,标记名称(如slow、requires_gpu、api_integration)放在冒号前面,后面是对标记的简短描述。这些标记可以在命令行中通过-m选项进行筛选。

2、通过conftest.py文件:

在项目的任意层级(通常是与待测试代码相近的位置)创建或编辑conftest.py文件。在其中,可以通过重写pytest_configure(config)函数来注册标记。例如:

# conftest.pyimport pytestdef pytest_configure(config):"""Register custom pytest markers."""config.addinivalue_line("markers",#参数 "markers"指定了要添加到哪个键下。markers 键是用来存储所有自定义标记定义的。"performance: mark a test as measuring performance, ""may be used for long-running tests" #这是添加到markers键下的值。它是一个字符串,格式为 <marker_name>: <marker_description> 也就是"performance"是标记名称,冒号后面为标记描述) config.addinivalue_line("markers","network: mark tests that require network connectivity")config.addinivalue_line("markers","critical: mark tests that verify critical functionality, ""should always be included in regression testing")

这里使用config.addinivalue_line()方法向markers键添加新的标记定义。在这个例子中,我们定义了三个标记:performance、network和critical。每个标记都有一个简短的描述,说明其含义和使用场景。config.addinivalue_line()方法用于向markers键添加新的标记定义。

八、标记与第三方插件的集成

许多 pytest 插件会识别并利用标记来扩展测试功能。Allure是一个通用的测试报告工具,提供了详细的测试执行历史、丰富的图表和交互式界面。allure-pytest插件将pytest与Allure报告系统紧密集成,使得pytest标记可以在Allure报告中发挥重要作用。

  • 标记分类:Allure报告可以按标记对测试进行分类展示。在pytest测试中使用标记后,Allure报告会自动将标记作为测试的标签显示,方便用户按标记过滤和浏览测试结果。
  • 标记与标签:在Allure中,可以将pytest标记映射为特定的Allure标签,以便在报告中以特定样式呈现或进行特定分析。这通常通过在pytest.ini或conftest.py中配置allure_markers来实现。
  • 标记与测试步骤:某些Allure插件(如allure-behave)支持将pytest标记关联到测试步骤,以便在报告中突出显示关键步骤或标记特定行为。
[pytest]
allure_markers =smoke: smokecritical: criticalregression: regression

相关内容会持续在pytest框架专栏中拓展,大家多多关注~

希望上述内容能帮助到大家理解使用pytest框架的测试标记@pytest.mark.<marker_name>

这篇关于Python的pytest框架(5)--测试标记(Markers)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926203

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个?

跨平台系列 cross-plateform 跨平台应用程序-01-概览 cross-plateform 跨平台应用程序-02-有哪些主流技术栈? cross-plateform 跨平台应用程序-03-如果只选择一个框架,应该选择哪一个? cross-plateform 跨平台应用程序-04-React Native 介绍 cross-plateform 跨平台应用程序-05-Flutte