详谈pytest中的xfail
详谈pytest中的xfail
原文链接: https://docs.pytest.org/en/7.2.x/how-to/skipping.html
链接中详细阐述了skip和xfail两种情况
- xfail 应该译作expected fail,预期失败(我知道这个用例是因为某些原因会失败的)
- 有哪些原因呢?
- 暂未实现的功能
- 实现的功能有bug
- 如果一个本应失败的用例通过了,那会标记为XPASS,失败是符合预期的,应显示为XFAIL
使用方法
装饰器用法及入门
示例代码
# demo.py #
import pytest def add(x,y):
return x*y # 这个功能有问题 @pytest.mark.xfail # 你知道这个case会失败,才打了这个标记
def test_add():
assert add(2,3) == 5 # 你预期是5,哪怕你知道结果会是6,你应该要写最终的 if __name__ == '__main__':
pytest.main(['-sv',__file__])
示例输出
test_xfail.py::test_add XFAIL
如果你不带-v得到的结果是
pytest.main(['-s',__file__]) test_xfail.py x # 注意,此处是小写的x
如果开发解决了这个bug,但你不知道,你运行你的用例,得到的结果是XPASS
import pytest def add(x,y):
return x+y # 这个功能解决了 @pytest.mark.xfail # 你以为这个case会失败,实际开发解决了,没告诉你,才打了这个标记
def test_add():
assert add(2,3) == 5 if __name__ == '__main__':
pytest.main(['-sv',__file__])
示例输出
test_xfail.py::test_add XPASS
同样的,你不带-v运行
pytest.main(['-s',__file__]) test_xfail.py X # 此处是大写的X
函数内嵌在用例中
示例代码
import pytest def valid_config():
'''
做了一些配置
'''
return False # 应该返回True def test_function1():
if not valid_config():
pytest.xfail('配置失败了...')
else:
print('配置成功,继续测试') if __name__ == '__main__':
pytest.main(['-sv',__file__])
示例输出
test_xfail.py::test_function1 XFAIL (配置失败了...)
pytest.mark.xfail中的参数
概览
pytest.mark.xfail(condition=None, *, reason=None, raises=None, run=True, strict=False)¶
参数说明
参数 类型 说明 condition bool or str Condition for marking the test function as xfail (True/False or a condition string). If a bool, you also have to specify reason reason str Reason why the test function is marked as xfail. raises Type[Exception] Exception subclass (or tuple of subclasses) expected to be raised by the test function; other exceptions will fail the test. run bool If the test function should actually be executed. If False, the function will always xfail and will not be executed (useful if a function is segfaulting). strict bool If False (the default) the function will be shown in the terminal output as xfailed if it fails and as xpass if it passes. In both cases this will not cause the test suite to fail as a whole. This is particularly useful to mark flaky tests (tests that fail at random) to be tackled later. If True, the function will be shown in the terminal output as xfailed if it fails, but if it unexpectedly passes then it will fail the test suite. This is particularly useful to mark functions that are always failing and there should be a clear indication if they unexpectedly start to pass (for example a new release of a library fixes a known bug)
condition参数
condition参数可以是字符串或布尔值(更常见),这是xfail生效的条件
示例代码
import pytest age = 24 @pytest.mark.xfail(age>=18,reason='年龄满足大于等于18岁')
def test_function():
assert False # 你预期这个用例是失败的才加xfail,所以你这里应该是False if __name__ == '__main__':
pytest.main(['-sv', __file__])
注意,当条件满足的时候(age=24,大于18),这个xfail会加到被测函数上
此时的结果就是
test_xfail.py::test_function XFAIL (年龄满足大于等于18岁)
如果改为age = 16
运行结果是
test_xfail.py:6: AssertionError
=========================== short test summary info ===========================
FAILED test_xfail.py::test_function - assert False
============================== 1 failed in 0.07s ==============================
意思就是条件不满足了,你的xfail不会挂到被测函数上
#@pytest.mark.xfail(age>=18,reason='年龄满足大于等于18岁') # 相当于去掉,注释掉了
def test_function():
assert False
有的时候是无条件的(跟运行环境无关),那你直接写为True即可
@pytest.mark.xfail(True,reason='这个case目前有BUG')
def test_function():
assert False
# test_xfail.py::test_function XFAIL (这个case目前有BUG)注意,当condition是布尔值的时候,reason参数是必须要写的,否则会报错
@pytest.mark.xfail(True)
def test_function():
assert False
# Error evaluating 'xfail': you need to specify reason=STRING when using booleans as conditions.
condition的值是str的话,可以不传reason,但也不能随便传
@pytest.mark.xfail('what')
def test_function():
assert False
会提示
name 'what' is not defined During handling of the above exception, another exception occurred:
Error evaluating 'xfail' condition
what
你写的str应该是可以用python的eval处理的一个expression,比如这样
@pytest.mark.xfail('True') @pytest.mark.xfail('False') @pytest.mark.xfail('sys.version_info >= (3,11)') # 当前的python版本是否大于等于3.11
def test_function():
...
reason参数
为何会标记为xfail的原因,就是个字符串
示例代码
@pytest.mark.xfail(reason="known issue")
def test_function():
assert False
示例结果
test_xfail.py::test_function XFAIL (known parser issue)
没有-v可看不到
raises参数
你预期这个case会出现某个exception(或者多个),如果是其他的exception会让这个用例失败
示例代码
@pytest.mark.xfail(raises=NameError)
def test_function():
print(a) # a没有定义
assert True
结果会是XFAIL:test_xfail.py::test_function XFAIL
如果你改为其他的exception,你raises的只有NameError
@pytest.mark.xfail(raises=NameError)
def test_function():
print(3/0) # ZeroDivisionError
assert True
此时的结果
=========================== short test summary info ===========================
FAILED test_xfail.py::test_function - ZeroDivisionError: division by zero
============================== 1 failed in 0.11s ==============================
如果要多个exception,就写到tuple里面即可
@pytest.mark.xfail(raises=(NameError,ZeroDivisionError))
def test_function():
print(3/0)
print(a)
assert True # 其实跟此处的True或者False无关,只要报出来exception,都会标记用例为XFAIL
run参数
If the test function should actually be executed. If
False, the function will always xfail and will not be executed (useful if a function is segfaulting).说那么多,意思其实是,你如果设置run=False,就不会去运行你的用例,直接就标记为XFAIL了
示例代码
@pytest.mark.xfail(run=False)
def test_function():
print('hello')
assert False
结果是这样的
test_xfail.py::test_function XFAIL ([NOTRUN] )
run=True是默认行为,不写就是之前所有的测试效果咯
strict 参数
如果你了这个参数,并设置为strict=True,那么XPASS就不存在了,会被标记为failed
先来个没有strict的,回忆下
@pytest.mark.xfail(True,reason='KNOWN BUG')
def test_function():
assert True
结果是XPASSED
加参数
@pytest.mark.xfail(True,reason='KNOWN BUG',strict=True)
def test_function():
assert True
结果是这样的
================================== FAILURES ===================================
________________________________ test_function ________________________________
[XPASS(strict)] KNOWN BUG
=========================== short test summary info ===========================
FAILED test_xfail.py::test_function
============================== 1 failed in 0.06s ==============================
如果你case是False的,那无论这个strict是否为True(不写就是为False),结果都是XFAIL
等价的写法,写到pytest.ini
[pytest]
xfail_strict=true
抛弃xfail
如果哪一天你在你的代码中写了很多的xfail
一个个去掉略显麻烦
好的处理方法就是加个命令行参数--runxfail
示例代码:下面的代码有--runxfail和没有,你可以执行看看
import pytest @pytest.mark.xfail
def test_function1():
assert False @pytest.mark.xfail
def test_function2():
assert False if __name__ == '__main__':
pytest.main(['-sv', '--runxfail',__file__])
也等价于
[pytest]
addopts = --runxfail
详谈pytest中的xfail的更多相关文章
- 2、pytest中文文档--使用和调用
目录 使用和调用 通过python -m pytest调用pytest *pytest执行结束时返回的状态码 pytest命令执行结束,可能会返回以下六种状态码: *获取帮助信息 最多允许失败的测试用 ...
- pytest中怎么实现参数化?
我们在组自动化项目中,肯定会遇到需要数据驱动的地方,在unittest中我们直接采用ddt的方式,但是在pytest中我们不能用ddt来实现,所以我们采用了参数化的方式来实现 那么具体怎么完成这个参数 ...
- pytest中怎么引用前置中的变量
本文主要总结的是pytest中的前置后置怎么返回参数 我们在做自动化的过程中,如果运用的是pytest的话,会遇到怎么使用前置条件中的变量 比如: @pytest.fixture() def init ...
- pytest-pyppeteer:在pytest中运行pyppeteer
pytest-pyppeteer pytest-pyppeteer是我写的一个 pytest 插件,支持在 pytest 中运行pyppeteer,起因是为了解决工作中的一个测试需求,现在将其开源并做 ...
- utittest和pytest中mock的使用详细介绍
头号玩家 模拟世界 单元测试库介绍 mock Mock是Python中一个用于支持单元测试的库,它的主要功能是使用mock对象替代掉指定的Python对象,以达到模拟对象的行为. python3.3 ...
- 『德不孤』Pytest框架 — 12、Pytest中Fixture装饰器(二)
目录 5.addfinalizer关键字 6.带返回值的Fixture 7.Fixture实现参数化 (1)params参数的使用 (2)进阶使用 8.@pytest.mark.usefixtures ...
- 『德不孤』Pytest框架 — 14、Pytest中的conftest.py文件
目录 1.conftest.py文件介绍 2.conftest.py的注意事项 3.conftest.py的使用 4.不同位置conftest.py文件的优先级 5.conftest.py中Fixtu ...
- 浅谈Pytest中的warning处理
浅谈Pytest中的warning处理 没有处理warning 我们写一个简单的测试 import pytest def test_demo(): import warnings warnings.w ...
- 浅谈Pytest中的marker
浅谈Pytest中的marker 没有注册marker 我们写一个简单的测试 # test_demo.py import pytest @pytest.mark.login def test_demo ...
- 3、pytest中文文档--编写断言
目录 编写断言 使用assert编写断言 编写触发期望异常的断言 特殊数据结构比较时的优化 为失败断言添加自定义的说明 关于断言自省的细节 复写缓存文件 去使能断言自省 编写断言 使用assert编写 ...
随机推荐
- 数据库可视化工具分享 (DBeaver)
前提:最近公司下发通知,所有开发人员 必须 卸载 Navicat 数据库可视化工具,不知道兄弟们有没有在使用的,可能现在的反应跟我一样,一脸懵逼,Navicat为什么不能使用呢? 有事没事找度娘,于是 ...
- 【Java并发006】使用层面:Lock锁机制全解析
一.前言 二.synchronized局限性 + Lock锁机制的引入 2.1 synchronized局限性 第一,使用synchronized,其他线程只能等待直到持有锁的线程执行完释放锁(syn ...
- 【ASP.NET Core】MVC控制器的各种自定义:修改参数的名称
在上一篇中,老周演示了通过实现约定接口的方式自定义控制器的名称. 至于说自定义操作方法的名称,就很简单了,因为有内置的特性类可以用.看看下面的例子. [Route("[controller] ...
- Dev-Cpp下载与安装
目录 一.介绍 Dev-Cpp 二.下载 Dev-Cpp 1.通过百度网盘下载 2.通过 SourceForge 官网下载 三.安装 Dev-Cpp 写在结尾的话 免责声明 大家好,这里是 main工 ...
- C++编程笔记(智能指针学习)
目录 scoped_ptr unique_ptr shared_ptr 智能指针简单应用 智能指针简单应用 scoped_ptr 拷贝构造和 =赋值操作均为私有,不允许 内部重载了解引用(*)操作符和 ...
- 【Day04】Spring Cloud 升华篇:容器化技术docker和kurbernetes
一.介绍 1.要考虑的问题 微服务数量有很多 中间件的部署-nacos-server sentinel-server 如何部署多个服务和中间件? 2.存在问题---机器上直接解压使用 资源利用率的问题 ...
- 连表操作join 子查询 SQL补充 数据库软件navicat pymysql模块
目录 多表查询的两种方法 方式1:连表操作 方式2:子查询 SQL补充知识点 1.分组之前字段拼接 concat concat_ws 2.SQL执行判断条件 exists 3.表相关SQL补充 修改表 ...
- C#中的进程检测退出事件和座位状态改变事件深入浅出谈谈EventHandler的使用
关于进程 之前我在启动我的师生对讲的exe的时候,都是直接调用Process类的静态函数Process.Start(System.String AppPath,System.String Argume ...
- 【深入浅出Spring原理及实战】「源码原理实战」从底层角度去分析研究PropertySourcesPlaceholderConfigurer的原理及实战注入机制
Spring提供配置解析功能 主要有一下xml文件占位符解析和Java的属性@Value的占位符解析配置这两种场景进行分析和实现解析,如下面两种案例. xml文件的占位符解析配置 <bean i ...
- VC实例和VM实例的区别!!!
1.内置关系是什么 VueComponent.prototype.__proto__ === Vue.prototype 2.为什么要有这个关系 让组件实例对象可以访问到 Vue原型上的属性.方法.