pytest中文使用文档----10skip和xfail标记
- 1. 跳过测试用例的执行
- 1.1.
@pytest.mark.skip装饰器 - 1.2.
pytest.skip方法 - 1.3.
@pytest.mark.skipif装饰器 - 1.4.
pytest.importorskip方法 - 1.5. 跳过测试类
- 1.6. 跳过测试模块
- 1.7. 跳过指定文件或目录
- 1.8. 总结
- 1.1.
- 2. 标记用例为预期失败的
- 2.1. 去使能
xfail标记
- 2.1. 去使能
- 3. 结合
pytest.param方法
实际工作中,测试用例的执行可能会依赖于一些外部条件,例如:只能运行在某个特定的操作系统(Windows),或者我们本身期望它们测试失败,例如:被某个已知的Bug所阻塞;如果我们能为这些用例提前打上标记,那么pytest就相应地预处理它们,并提供一个更加准确的测试报告;
在这种场景下,常用的标记有:
skip:只有当某些条件得到满足时,才执行测试用例,否则跳过整个测试用例的执行;例如,在非Windows平台上跳过只支持Windows系统的用例;xfail:因为一个确切的原因,我们知道这个用例会失败;例如,对某个未实现的功能的测试,或者阻塞于某个已知Bug的测试;
pytest默认不显示skip和xfail用例的详细信息,我们可以通过-r选项来自定义这种行为;
通常,我们使用一个字母作为一种类型的代表,具体的规则如下:
(f)ailed, (E)rror, (s)kipped, (x)failed, (X)passed, (p)assed, (P)assed with output, (a)ll except passed(p/P), or (A)ll
例如,显示结果为XFAIL、XPASS和SKIPPED的用例:
pytest -rxXs
更多细节可以参考:2、使用和调用 – 总结报告
1. 跳过测试用例的执行
1.1. @pytest.mark.skip装饰器
跳过执行某个用例最简单的方式就是使用@pytest.mark.skip装饰器,并且可以设置一个可选参数reason,表明跳过的原因;
@pytest.mark.skip(reason="no way of currently testing this")
def test_the_unknown():...
1.2. pytest.skip方法
如果我们想在测试执行期间(也可以在SetUp/TearDown期间)强制跳过后续的步骤,可以考虑pytest.skip()方法,它同样可以设置一个参数msg,表明跳过的原因;
def test_function():if not valid_config():pytest.skip("unsupported configuration")
另外,我们还可以为其设置一个布尔型的参数allow_module_level(默认是False),表明是否允许在模块中调用这个方法,如果置为True,则跳过模块中剩余的部分;
例如,在Windows平台下,不测试这个模块:
import sys
import pytestif not sys.platform.startswith("win"):pytest.skip("skipping windows-only tests", allow_module_level=True)
注意:
当在用例中设置
allow_module_level参数时,并不会生效;def test_one():pytest.skip("跳出", allow_module_level=True)def test_two():assert 1也就是说,在上述示例中,并不会跳过
test_two用例;
1.3. @pytest.mark.skipif装饰器
如果我们想有条件的跳过某些测试用例的执行,可以使用@pytest.mark.skipif装饰器;
例如,当python的版本小于3.6时,跳过用例:
import sys@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
def test_function():...
我们也可以在两个模块之间共享pytest.mark.skipif标记;
例如,我们在test_module.py中定义了minversion,表明当python的最低支持版本:
# src/chapter-10/test_module.pyimport sysimport pytestminversion = pytest.mark.skipif(sys.version_info < (3, 8),reason='请使用 python 3.8 或者更高的版本。')@minversion
def test_one():assert True
并且,在test_other_module.py中引入了minversion:
# src/chapter-10/test_other_module.pyfrom test_module import minversion@minversion
def test_two():assert True
现在,我们来执行这两个用例(当前虚拟环境的python版本为3.7.3):
λ pytest -rs -k 'module' src/chapter-10/
================================ test session starts =================================
platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0
rootdir: D:\Personal Files\Projects\pytest-chinese-doc
collected 2 itemssrc\chapter-10\test_module.py s [ 50%]
src\chapter-10\test_other_module.py s [100%]============================== short test summary info ===============================
SKIPPED [1] src\chapter-10\test_module.py:29: 请使用 python 3.8 或者更高的版本。
SKIPPED [1] src\chapter-10\test_other_module.py:26: 请使用 python 3.8 或者更高的版本。
================================= 2 skipped in 0.03s =================================
可以看到,minversion在两个测试模块中都生效了;
因此,在大型的测试项目中,可以在一个文件中定义所有的执行条件,需要时再引入到模块中;
另外,需要注意的是,当一个用例指定了多个skipif条件时,只需满足其中一个,就可以跳过这个用例的执行;
注意:不存在
pytest.skipif()的方法;
1.4. pytest.importorskip方法
当引入某个模块失败时,我们同样可以跳过后续部分的执行;
docutils = pytest.importorskip("docutils")
我们也可以为其指定一个最低满足要求的版本,判断的依据是检查引入模块的__version__ 属性:
docutils = pytest.importorskip("docutils", minversion="0.3")
我们还可以再为其指定一个reason参数,表明跳过的原因;
我们注意到
pytest.importorskip和pytest.skip(allow_module_level=True)都可以在模块的引入阶段跳过剩余部分;实际上,在源码中它们抛出的都是同样的异常:# pytest.skip(allow_module_level=True)raise Skipped(msg=msg, allow_module_level=allow_module_level)# pytest.importorskip()raise Skipped(reason, allow_module_level=True) from None只是
importorskip额外增加了minversion参数:# _pytest/outcomes.pyif minversion is None:return modverattr = getattr(mod, "__version__", None)if minversion is not None:if verattr is None or Version(verattr) < Version(minversion):raise Skipped("module %r has __version__ %r, required is: %r"% (modname, verattr, minversion),allow_module_level=True,)从中我们也证实了,它实际检查的是模块的
__version__属性;所以,对于一般场景下,使用下面的方法可以实现同样的效果:
try:import docutils except ImportError:pytest.skip("could not import 'docutils': No module named 'docutils'",allow_module_level=True)
1.5. 跳过测试类
在类上应用@pytest.mark.skip或@pytest.mark.skipif:
# src/chapter-10/test_skip_class.pyimport pytest@pytest.mark.skip("作用于类中的每一个用例,所以 pytest 共收集到两个 SKIPPED 的用例。")
class TestMyClass():def test_one(self):assert Truedef test_two(self):assert True
1.6. 跳过测试模块
在模块中定义pytestmark变量(推荐):
# src/chapter-10/test_skip_module.pyimport pytestpytestmark = pytest.mark.skip('作用于模块中的每一个用例,所以 pytest 共收集到两个 SKIPPED 的用例。')def test_one():assert Truedef test_two():assert True
或者,在模块中调用pytest.skip方法,并设置allow_module_level=True:
# src/chapter-10/test_skip_module.pyimport pytestpytest.skip('在用例收集阶段就已经跳出了,所以不会收集到任何用例。', allow_module_level=True)def test_one():assert Truedef test_two():assert True
1.7. 跳过指定文件或目录
通过在conftest.py中配置collect_ignore_glob项,可以在用例的收集阶段跳过指定的文件和目录;
例如,跳过当前测试目录中文件名匹配test_*.py规则的文件和config的子文件夹sub中的文件:
collect_ignore_glob = ['test*.py', 'config/sub']
更多细节可以参考:https://docs.pytest.org/en/5.1.3/example/pythoncollection.html#customizing-test-collection
1.8. 总结
pytest.mark.skip | pytest.mark.skipif | pytest.skip | pytest.importorskip | conftest.py | |
|---|---|---|---|---|---|
| 用例 | @pytest.mark.skip() | @pytest.mark.skipif() | pytest.skip(msg='') | / | / |
| 类 | @pytest.mark.skip() | @pytest.mark.skipif() | / | / | / |
| 模块 | pytestmark = pytest.mark.skip() | pytestmark = pytest.mark.skipif() | pytest.skip(allow_module_level=True) | pytestmark = pytest.importorskip() | / |
| 文件或目录 | / | / | / | / | collect_ignore_glob |
2. 标记用例为预期失败的
我们可以使用@pytest.mark.xfail标记用例,表示期望这个用例执行失败;
用例会正常执行,只是失败时不再显示堆栈信息,最终的结果有两个:用例执行失败时(XFAIL:符合预期的失败)、用例执行成功时(XPASS:不符合预期的成功)
另外,我们也可以通过pytest.xfail方法在用例执行过程中直接标记用例结果为XFAIL,并跳过剩余的部分:
def test_function():if not valid_config():pytest.xfail("failing configuration (but should work)")
同样可以为pytest.xfail指定一个reason参数,表明原因;
下面我们来重点看一下@pytest.mark.xfail的用法:
-
condition位置参数,默认值为None和
@pytest.mark.skipif一样,它也可以接收一个python表达式,表明只有满足条件时才标记用例;例如,只在
pytest 3.6版本以上标记用例:@pytest.mark.xfail(sys.version_info >= (3, 6), reason="python3.6 api changes") def test_function():... -
reason关键字参数,默认值为None可以指定一个字符串,表明标记用例的原因;
-
strict关键字参数,默认值为False当
strict=False时,如果用例执行失败,结果标记为XFAIL,表示符合预期的失败;如果用例执行成功,结果标记为XPASS,表示不符合预期的成功;当
strict=True时,如果用例执行成功,结果将标记为FAILED,而不再是XPASS了;我们也可以在
pytest.ini文件中配置:[pytest] xfail_strict=true -
raises关键字参数,默认值为None可以指定为一个异常类或者多个异常类的元组,表明我们期望用例上报指定的异常;
如果用例的失败不是因为所期望的异常导致的,
pytest将会把测试结果标记为FAILED; -
run关键字参数,默认值为True:当
run=False时,pytest不会再执行测试用例,直接将结果标记为XFAIL;
我们以下表来总结不同参数组合对测试结果的影响(其中xfail = pytest.mark.xfail):
@xfail() | @xfail(strict=True) | @xfail(raises=IndexError) | @xfail(strict=True, raises=IndexError) | @xfail(..., run=False) | |
|---|---|---|---|---|---|
| 用例测试成功 | XPASS | FAILED | XPASS | FAILED | XFAIL |
用例测试失败,上报AssertionError | XFAIL | XFAIL | FAILED | FAILED | XFAIL |
用例上报IndexError | XFAIL | XFAIL | XFAIL | XFAIL | XFAIL |
2.1. 去使能xfail标记
我们可以通过命令行选项pytest --runxfail来去使能xfail标记,使这些用例变成正常执行的用例,仿佛没有被标记过一样:
同样,pytest.xfail()方法也将会失效;
3. 结合pytest.param方法
pytest.param方法可用于为@pytest.mark.parametrize或者参数化的fixture指定一个具体的实参,它有一个关键字参数marks,可以接收一个或一组标记,用于标记这轮测试的用例;
我们以下面的例子来说明:
# src/chapter-10/test_params.pyimport pytest
import sys@pytest.mark.parametrize(('n', 'expected'),[(2, 1),pytest.param(2, 1, marks=pytest.mark.xfail(), id='XPASS'),pytest.param(0, 1, marks=pytest.mark.xfail(raises=ZeroDivisionError), id='XFAIL'),pytest.param(1, 2, marks=pytest.mark.skip(reason='无效的参数,跳过执行')),pytest.param(1, 2, marks=pytest.mark.skipif(sys.version_info <= (3, 8), reason='请使用3.8及以上版本的python。'))])
def test_params(n, expected):assert 2 / n == expected
执行:
λ pytest -rA src/chapter-10/test_params.py
================================ test session starts =================================
platform win32 -- Python 3.7.3, pytest-5.1.3, py-1.8.0, pluggy-0.13.0
rootdir: D:\Personal Files\Projects\pytest-chinese-doc
collected 5 itemssrc\chapter-10\test_params.py .Xxss [100%]======================================= PASSES =======================================
============================== short test summary info ===============================
PASSED src/chapter-10/test_params.py::test_params[2-1]
SKIPPED [1] src\chapter-10\test_params.py:26: 无效的参数,跳过执行
SKIPPED [1] src\chapter-10\test_params.py:26: 请使用3.8及以上版本的python。
XFAIL src/chapter-10/test_params.py::test_params[XFAIL]
XPASS src/chapter-10/test_params.py::test_params[XPASS]
================= 1 passed, 2 skipped, 1 xfailed, 1 xpassed in 0.08s =================
关于参数化的fixture的细节可以参考:4、fixtures:明确的、模块化的和可扩展的 – 在参数化的fixture中标记用例
相关文章:
pytest中文使用文档----10skip和xfail标记
1. 跳过测试用例的执行 1.1. pytest.mark.skip装饰器1.2. pytest.skip方法1.3. pytest.mark.skipif装饰器1.4. pytest.importorskip方法1.5. 跳过测试类1.6. 跳过测试模块1.7. 跳过指定文件或目录1.8. 总结 2. 标记用例为预期失败的 2.1. 去使能xfail标记 3. 结合pytest.param方…...
【Spring MVC】快速学习使用Spring MVC的注解及三层架构
💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:【Spring MVC】快速学习使用Spring MVC的注解及三层架构 🎉欢迎大家点赞👍评论📝收藏⭐文章 目录 Spring Web MVC一: 什么是Spring Web MVC࿱…...
Python(乱学)
字典在转化为其他类型时,会出现是否舍弃value的操作,只有在转化为字符串的时候才不会舍弃value 注释的快捷键是ctrl/ 字符串无法与整数,浮点数,等用加号完成拼接 5不入??? 还有一种格式化的方法…...
OpenHarmony实战:轻量级系统之子系统移植概述
OpenHarmony系统功能按照“系统 > 子系统 > 部件”逐级展开,支持根据实际需求裁剪某些非必要的部件,本文以部分子系统、部件为例进行介绍。若想使用OpenHarmony系统的能力,需要对相应子系统进行适配。 OpenHarmony芯片适配常见子系统列…...
Neo4j基础知识
图数据库简介 图数据库是基于数学里图论的思想和算法而实现的高效处理复杂关系网络的新型数据库系统。它善于高效处理大量的、复杂的、互连的、多变的数据。其计算效率远远高于传统的关系型数据库。 在图形数据库当中,每个节点代表一个对象,节点之间的…...
HTTP/1.1 特性(计算机网络)
HTTP/1.1 的优点有哪些? 「简单、灵活和易于扩展、应用广泛和跨平台」 1. 简单 HTTP 基本的报文格式就是 header body,头部信息也是 key-value 简单文本的形式,易于理解。 2. 灵活和易于扩展 HTTP 协议里的各类请求方法、URI/URL、状态码…...
每日一题————P5725 【深基4.习8】求三角形
题目: 题目乍一看非常的简单,属于初学者都会的问题——————————但是实际上呢,有一些小小的坑在里面。 就是三角形的打印。 平常我们在写代码的时候,遇到打印三角形的题,一般简简单单两个for循环搞定 #inclu…...
第三题:时间加法
题目描述 现在时间是 a 点 b 分,请问 t 分钟后,是几点几分? 输入描述 输入的第一行包含一个整数 a。 第二行包含一个整数 b。 第三行包含一个整数 t。 其中,0≤a≤23,0≤b≤59,0≤t, 分钟后还是在当天。 输出描…...
【RAG】内部外挂知识库搭建-本地GPT
大半年的项目告一段落了,现在自己找找感兴趣的东西学习下,看看可不可以搞出个效果不错的local GPT,自研下大模型吧 RAG是什么? 检索增强生成(RAG)是指对大型语言模型输出进行优化,使其能够在生成响应之前引用训练数据来…...
MySQL——锁
全局锁 全局锁是一种数据库锁定机制,它可以锁定整个数据库,阻止其他会话对数据库的读写操作。在MySQL中,全局锁定可以使用FLUSH TABLES WITH READ LOCK命令来实现。执行这个命令后,MySQL将获取一个全局读锁,直到当前会…...
C++(12): std::mutex及其高级变种的使用
1. 简述 在多线程或其他许多场景下,同时对一个变量或一段资源进行读写操作是一个比较常见的过程,保证数据的一致性和防止竞态条件至关重要。 C的标准库中为我们提供了使用的互斥及锁对象,帮助我们实现资源的互斥操作。 2. std::mutex及其衍…...
基于ROS软路由的百元硬件升级方案实现突破千兆宽带
前言 很多用户得利于FTTR光网络不断推广,家用宽带带宽已经实现千兆速率的突破。而现在很多ISP运营商已经在多个城市率先推出2000M光宽带。这种情况下,要想将自家宽带的带宽能够充分发挥利用,就需要对原有的千兆设备进行升级来满足突破千兆的…...
OpenHarmony实战开发-分布式关系型数据库
介绍 本示例使用ohos.data.relationalStore 接口和ohos.distributedDeviceManager 接口展示了在eTS中分布式关系型数据库的使用,在增、删、改、查的基本操作外,还包括分布式数据库的数据同步同能。 效果预览 使用说明: 1.启动应用后点击“”按钮可以添…...
图片标注编辑平台搭建系列教程(6)——fabric渲染原理
原理 fabric的渲染步骤大致如下: 渲染前都设置背景图然后调用ctx.save(),存储画布的绘制状态参数然后调用每个object自身的渲染方法最后调用ctx.restore(),恢复画布的保存状态后处理,例如控制框的渲染等 值得注意的是࿰…...
Qt中QIcon图标设置(标题、菜单栏、工具栏、状态栏图标)
1 exe程序图标概述 在 Windows 操作系统中,程序图标一般会涉及三个地方; (1) 可执行程序(以及对应的快捷方式)的图标 (2) 程序界面标题栏图标 (3)程序在任务…...
C语言程序10题
第101题 (10.0分) 难度:易 第2章 /*------------------------------------------------------- 【程序填空】 --------------------------------------------------------- 功能:计算平均成绩并统计90分以上人数。 --…...
定时器-间歇函数
1.开启定时器 setInterval(function (){console.log(一秒执行一次)},1000) function fn(){console.log(一秒执行一次) } setInterval(fn,1000) //调用有名的函数,只写函数名 1.函数名字不需要加小括号 2.定时器返回是一个id数字 每个定时器的序号是不一样的 2.关…...
Ajax-XMLHttpRequest基本使用
一、Ajax的原理 就是XMLHttpRequest对象。 二、为什么学习XHR? 有更多与服务器数据通信方式,了解Ajax内部。 三、XHR使用步骤 1.创建XHR对象 2.调用open方法,设置url和请求方法 3.监听loadend事件,接受结果 4.调用send方法…...
门控循环单元(GRU)
概述 门控循环单元(Gated Recurrent Unit, GRU)由Junyoung Chung等人于2014年提出,原论文为《Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling》。GRU是循环神经网络(Recurrent Neural Network, …...
789. 数的范围 (二分学习)左端大右,右端小左
题目链接https://www.acwing.com/file_system/file/content/whole/index/content/4317/ 当求左端点时,条件是a【mid】大于等于x,并把右端点缩小。 当求右端点时,条件是a【mid】小于等于x,并把左端点扩大。 1.确定一个区间&…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
