【pytest】pytest注解使用指南

ops/2024/11/23 6:09:49/

前言:在 pytest 测试框架中,注解(通常称为装饰器)用于为测试函数、类或方法提供额外的信息或元数据。这些装饰器可以影响测试的执行方式、报告方式以及测试的组织结构。pytest 提供了多种内置的装饰器,以及通过插件扩展的额外装饰器

以下是一些常用的 pytest 装饰器及其用途:

1、@pytest.mark.parametrize

  • 用于参数化测试,允许您为测试函数提供多个参数集,pytest 将为每个参数集运行一次测试。
  • 示例:@pytest.mark.parametrize("input,expected", [(1, 2), (3, 4)])
import pytest@pytest.mark.parametrize("input,expected", [(1, 2), (3, 4), (5, 6)])
def test_addition(input, expected):assert input + 1 == expected

在这个例子中,test_addition 函数将使用三组不同的参数((1, 2)(3, 4)(5, 6))分别运行三次。 

2、@pytest.mark.skip 和 @pytest.mark.skipif

  • 用于跳过测试。@pytest.mark.skip 无条件跳过测试,而 @pytest.mark.skipif 根据条件跳过测试。
  • 示例:@pytest.mark.skip(reason="Not ready yet") 或 @pytest.mark.skipif(sys.version_info < (3, 6), reason="Python 3.6+ required")
import pytest
import sys# 无条件跳过
@pytest.mark.skip(reason="This test is not ready yet")
def test_not_ready():assert True# 根据条件跳过
@pytest.mark.skipif(sys.version_info < (3, 6), reason="Python 3.6+ required")
def test_python_version():assert True

 在第一个例子中,test_not_ready 函数将被无条件跳过。在第二个例子中,如果 Python 版本低于 3.6,test_python_version 函数将被跳过。

3、@pytest.mark.xfail 和 @pytest.mark.xfailif

  • 用于标记预期失败的测试。这些测试将被执行,但如果它们失败了,则不会被视为错误。
  • 示例:@pytest.mark.xfail(reason="Known issue") 或 @pytest.mark.xfailif(some_condition, reason="Condition not met")

注意:@pytest.mark.xfailif 不是 pytest 内置的,但可以通过类似逻辑实现条件性的 xfail

import pytest# 标记预期失败的测试
@pytest.mark.xfail(reason="This is a known issue")
def test_xfail():assert False# 可以通过编写一个函数来模拟 @pytest.mark.xfailif 的行为
def pytest_xfail_if(condition, reason):def decorator(func):if condition:func = pytest.mark.xfail(reason=reason)(func)return funcreturn decorator# 使用模拟的 @pytest.mark.xfailif
@pytest_xfail_if(True, reason="Condition met, expect failure")
def test_conditional_xfail():assert False

4、@pytest.mark.tryfirst 和 @pytest.mark.trylast

  • 用于控制测试的执行顺序,尤其是在有多个钩子函数(如 setup/teardown 方法)时。
  • 这些装饰器通常与 pytest 插件中的钩子函数一起使用。

通常与 pytest 插件中的钩子函数一起使用

# 假设有一个 pytest 插件提供了 setup 和 teardown 钩子函数
# 并且我们想要某个测试在这些钩子函数中首先或最后执行
# 注意:这里的示例是假设性的,因为 @pytest.mark.tryfirst 和 @pytest.mark.trylast
# 通常不直接用于测试函数,而是用于钩子函数或插件实现# 假设的 setup 和 teardown 钩子函数(实际上需要由 pytest 插件提供)
# @pytest.hookimpl(tryfirst=True)
# def pytest_setup():
#     pass# @pytest.hookimpl(trylast=True)
# def pytest_teardown():
#     pass# 假设的测试函数(实际上不会直接使用 @pytest.mark.tryfirst 或 @pytest.mark.trylast)
# @pytest.mark.tryfirst  # 这通常不会直接用于测试函数
def test_tryfirst():pass# @pytest.mark.trylast  # 这通常也不会直接用于测试函数
def test_trylast():pass

5、@pytest.mark.usefixtures

  • 用于声明测试将使用的 fixture。虽然这不是严格意义上的装饰器(因为它不直接修饰函数),但它用于指定测试依赖的 fixture。
  • 示例:@pytest.mark.usefixtures("my_fixture")
import pytest@pytest.fixture
def my_fixture():return "fixture value"@pytest.mark.usefixtures("my_fixture")
def test_with_fixture(my_fixture_value):assert my_fixture_value == "fixture value"# 注意:在实际使用中,pytest 会自动将 fixture 的值注入到测试函数中,
# 因此测试函数的参数名应与 fixture 的名称相匹配(或使用 pytest.mark.parametrize 来指定参数名)。
# 上面的示例中,为了说明 @pytest.mark.usefixtures 的用法,
# 假设了一个名为 my_fixture_value 的参数,但在实际代码中应直接使用 my_fixture。
# 正确的用法如下:
@pytest.mark.usefixtures("my_fixture")
def test_with_fixture_correct(my_fixture):assert my_fixture == "fixture value"

在这个例子中,test_with_fixture_correct 函数将使用名为 my_fixture 的 fixture。请注意,在实际代码中,您不需要(也不应该)在测试函数参数中显式地指定 fixture 的值;pytest 会自动将其注入 

6、@pytest.mark.filterwarnings

  • 用于控制测试期间应如何处理警告。
  • 示例:@pytest.mark.filterwarnings("ignore::DeprecationWarning")
import pytest
import warnings@pytest.mark.filterwarnings("ignore::DeprecationWarning")
def test_with_warnings():warnings.warn("This is a deprecation warning", DeprecationWarning)assert True

在这个例子中,test_with_warnings 函数将忽略 DeprecationWarning 类型的警告。

7、@pytest.mark.timeout(通过 pytest-timeout 插件提供):

  • 用于设置测试的超时时间。如果测试在指定时间内未完成,则将被标记为失败。
  • 示例:@pytest.mark.timeout(10)(10秒超时)
import pytest@pytest.mark.timeout(5)  # 设置超时时间为5秒
def test_with_timeout():import timetime.sleep(10)  # 这将触发超时失败assert True

 在这个例子中,test_with_timeout 函数将在5秒后超时失败,因为 time.sleep(10) 会使测试运行超过指定的超时时间。

8、@pytest.mark.flaky(通过 pytest-flaky 插件提供):

  • 用于标记可能间歇性失败的测试,并允许它们在一定数量的重试后通过。
  • 示例:@pytest.mark.flaky(reruns=3, reruns_delay=2)(重试3次,每次延迟2秒)
import pytest@pytest.mark.flaky(reruns=3, reruns_delay=1)  # 设置重试3次,每次延迟1秒
def test_flaky():import randomassert random.choice([True, False])  # 这将随机成功或失败

在这个例子中,test_flaky 函数将随机成功或失败。如果它失败了,pytest-flaky 插件将重试它最多3次,每次之间延迟1秒。

9、@pytest.mark.order(通过 pytest-order 插件提供):

  • 用于指定测试的执行顺序。
  • 示例:@pytest.mark.order(1)(数字越小,执行越早)
import pytest@pytest.mark.order(1)  # 设置执行顺序为1
def test_first():assert True@pytest.mark.order(2)  # 设置执行顺序为2
def test_second():assert True


在这个例子中,test_first 函数将先于 test_second 函数执行,因为它们的执行顺序被分别设置为1和2。

10、自定义标记

  • 您可以使用 @pytest.mark.<name> 语法创建自定义的标记,并在测试配置文件中定义它们的行为。
  • 示例:@pytest.mark.my_custom_mark(然后在 pytest.ini 或 pytest.mark 文件中定义它)
import pytest# 在 pytest.ini 或 pytest.mark 文件中定义自定义标记
# [pytest]
# markers =
#     my_custom_mark: This is a custom marker@pytest.mark.my_custom_mark  # 使用自定义标记
def test_with_custom_mark():assert True

 我们定义了一个名为 my_custom_mark 的自定义标记,并在 test_with_custom_mark 函数中使用了它。请注意,您需要在 pytest 的配置文件中(如 pytest.ini 或 pytest.mark)定义这个自定义标记,以便 pytest 能够识别它。

请注意,上述列表中的一些装饰器(如 @pytest.mark.timeout 和 @pytest.mark.flaky)是通过 pytest 插件提供的,因此在使用它们之前需要确保已安装相应的插件。

在使用这些装饰器时,请确保您了解它们如何影响测试的执行和报告,以及它们是否适用于您的测试场景。


http://www.ppmy.cn/ops/135996.html

相关文章

Ultiverse 和web3新玩法?AI和GameFi的结合是怎样

Gamef 和 AI 是我们这个周期十分看好两大赛道之一&#xff0c;(Gamef 拥有极强的破圈效应&#xff0c;引领 Web2 用户进军 Web3 最佳利器。AI是这个周期最热门赛道&#xff0c;无论 Web2的 OpenAl&#xff0c;还是 Web3&#xff0c;都成为话题热议焦点。那么结合 GamefiA1双叙事…

Typora-PicGo-OSS对象存储

Typora-PicGo-对象存储OSS 问题描述&#xff1a; 上次做完Gitee图床配置后&#xff0c;今天发现图床突然不能使用了&#xff0c;直到我查找到Gitee仓库变成私有后才发现做的图床被封禁了当前仓库因涉嫌外链滥用(RAW)&#xff0c;不支持设置为公开仓库&#xff0c;就导致我的笔…

MATLAB读入不同类型图像并显示图像和相关信息

MATLAB&#xff08;Matrix Laboratory)是一种常用的数学工具软件&#xff0c;MATLAB以矩阵运算为核心&#xff0c;为图像处理提供了高效的数据处理能力。图像处理中的许多操作都可以转化为矩阵运算&#xff0c;从而利用MATLAB的矩阵运算能力进行优化和加速。在图像处理方面&…

基于Spring Boot的同城宠物照看系统的设计与实现

摘 要 科学技术日新月异&#xff0c;人们的生活都发生了翻天覆地的变化&#xff0c;同城宠物照看系统当然也不例外。过去的信息管理都使用传统的方式实行&#xff0c;既花费了时间&#xff0c;又浪费了精力。在信息如此发达的今天&#xff0c;我们可以通过网络这个媒介&#x…

windows C#-异步返回类型(下)

Void 返回类型 在异步事件处理程序中使用 void 返回类型&#xff0c;这需要 void 返回类型。 对于事件处理程序以外的不返回值的方法&#xff0c;应返回 Task&#xff0c;因为无法等待返回 void 的异步方法。 此类方法的任何调用方都必须继续完成&#xff0c;而无需等待调用的…

Softing工业将OPC UA信息建模集成到边缘应用和安全集成服务器中

Softing工业宣布将OPC UA&#xff08;统一架构&#xff09;信息建模集成到其边缘产品系列及安全集成服务器&#xff08;SIS&#xff09;中&#xff0c;这一技术进步使得在工业物联网&#xff08;IIoT&#xff09;应用中的数据集成、交换与控制更加无缝、有效。 &#xff08;OPC…

没钱买KEGG怎么办?REACTOME开源通路更强大

之前搜集免费生物AI插图时简单提到了通路数据库Reactome&#xff08;https://reactome.org/&#xff09;&#xff0c; 那些精美的生物插图只能算是该数据库附赠的小礼品&#xff0c;他的主要功能还是作为一个开源的通路数据库&#xff0c;为相关领域的研究者提供直观的可视化生…

vue项目中富文本编辑器的实现

文章目录 vue前端实现富文本编辑器的功能需要用到第三方库1. 安装包2.全局引入注册3.组件内使用4.图片缩放功能实现①安装包②注册并添加配置项③报错解决 vue前端实现富文本编辑器的功能需要用到第三方库 vue2使用vue-quill-editor&#xff0c;vue3使用vueup/vue-quill&#…