Pytest内置标签xfail的用法

xfail可用于标记此用例可能会失败,当脚本失败时,测试报告也不会打印错误追踪,只是会显示xfail状态,xfail的主要作用是比如在进行测试提前时,当产品某功能尚未开发完成而进行自动化脚本开发,当然此时也可以把这些脚本注释起来,但这不是pytest推荐的做法,pytest推荐使用xfail标记,如此则虽然产品功能尚未开发完成,但是自动化脚本已经可以跑起来了,只不过在测试报告中会显示xfail而已。如下:

import pytest

@pytest.mark.xfail
def test_01():
    assert 1==2

执行结果如下:

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item

test_demo.py x                                                                                                                                                    [100%]

========================================================================== 1 xfailed in 2.35s ==========================================================================

而当产品功能开发完成后,脚本执行的结果会显示xpass状态,注意xpass不是内置标签,不能用于在脚本中标记,xpass是指用xfail标记的脚本在执行的过程中没有报错,因而脚本额执行状态为xpass状态。如下:

import pytest

@pytest.mark.xfail
def test_01():
    assert 1==1

执行结构如下:

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item

test_demo.py X                                                                                                                                                    [100%]

========================================================================== 1 xpassed in 2.15s ==========================================================================

可以看到这里显示xpassed状态,而当用例显示xpassed状态表示测试用例已经通过了,比如如果产品功能已经OK了,那么此时就可以将此脚本中的xfail标记去掉即可。

在一些场景下,需要通过判断一些条件,当满足一定条件时,就可以确认会失败,即此时可以xfail在满足一定条件时标记为xfail,然后标记后的代码则不会被执行。如下即判断当操作系统为windows系统时就标记为失败

import pytest
import platform

def test_01():
    if platform.system() == "Windows":
        pytest.xfail("Windows系统暂不支持")
        print("测试,windows系统下不应该打印出当前信息")
    print("不会打印当前信息")

执行结果如下,可以看出在标记xfail之后的所有代码都没有执行。

$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item

test_demo.py x

========================================================================== 1 xfailed in 2.25s ==========================================================================

这里需要格外注意,当在@pytest.mark.xfail装饰器的参数中也是可以添加条件判断的,这里需要特别注意的是并不是根据这里的条件判断是否为xfail或者xpass,这里的条件真假是决定当前测试脚本是否启用xfail标记的含义。如下代码中@pytest.mark.xfail后的条件判断,当在windows上执行时,即此时条件为真,此时的含义是启动xfail标记,

import pytest
import platform

@pytest.mark.xfail(platform.system() == "Windows",reason="不支持windows系统")
def test_01():
    assert 1==1

执行结果如下,即此时状态为xpass状态

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.7, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: D:\src\blog\tests, configfile: pytest.ini
plugins: allure-pytest-2.9.43, caterpillar-pytest-0.0.2, hypothesis-6.31.6, forked-1.3.0, rerunfailures-10.1, xdist-2.3.0
collected 1 item

test_demo.py X                                                                                                                                                    [100%]

========================================================================== 1 xpassed in 0.03s ==========================================================================

而当测试代码修改为如下,在此时在Windos系统运行时,@pytest.mark.xfail后面的条件此时为假,即此时的含义为对当前用例不启用xfail标记,只是一个普通用例。

import pytest
import platform

@pytest.mark.xfail(platform.system() == "Linux",reason="不支持windows系统")
def test_01():
    assert 1==1

执行结果如下,即此时的用例执行状态跟普通的测试脚本的执行状态是一样的,即要么断言通过,要么断言失败,即用例是吧。这里如下显示passed。

pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item

test_demo.py .                                                                                                                                                    [100%]

========================================================================== 1 passed in 0.04s ===========================================================================

当@pytest.mark.xfail装饰器只设置reason参数时,表示当前用例是启用xfail标记的,reason只是用来说明理由的,用例执行结果当然只能是xpass或者xfail。如下所示:

import pytest

@pytest.mark.xfail(reason="xxx")
def test_01():
    assert 1==1

执行结果如下,可以发现此时的执行结构为xpass状态。

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 1 item

test_demo.py X                                                                                                                                                    [100%]

========================================================================== 1 xpassed in 2.17s ==========================================================================

@pytest.mark.xfail装饰器可以通过设置run参数来限定是否执行测试函数,默认情况下载不指定run参数时是执行测试函数内容的,当设置run的参数值为False时,则直接将用例标记为xfail状态,而不去执行测试脚本了
test_demo.py代码如下:

import pytest

@pytest.mark.xfail(run=False)
def test_01():
    print("\n in test_01...")

@pytest.mark.xfail(run=True)
def test_02():
    print("\n in test_02...")

@pytest.mark.xfail()
def test_03():
    print("\n in test_03...")

执行结果如下,可以看出此时三个测试函数中都没有断言语句,按照断言的逻辑三个测试函数都应该断言成功,而其中test_01中run参数设置为FALSE,即此时test_01不会执行测试函数,而是直接标价为xfail,结果如下所示,并未打印”in test_01″,而且有一个用例状态为xfail状态。

$ pytest -s
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 3 items

test_demo.py x
 in test_02...

X
 in test_03...

X

==================================================================== 1 xfailed, 2 xpassed in 0.09s =====================================================================

xfail本本意是预料到或期望用例是失败的,但是当脚本断言成功后,此时脚本执行结果变为xpass,即通过了,与原本期望的xfail不一致了,因此在某些场景下,希望xpass状态的用例显示为失败,而xfail的用例依然为xfail状态,此时只需要使用strict参数即可,将strict参数设置为True,则执行结果原本为xpass的用例此时将变为失败

import pytest

@pytest.mark.xfail(strict=True)
def test_01():
    assert 1==1

@pytest.mark.xfail(strict=True)
def test_02():
    assert 1==2

执行结果如下,即此时test_01中原本之心结果为xpass状态的,此时变为FAILED状态了。

$ pytest
========================================================================= test session starts ==========================================================================
platform win32 -- Python 3.9.13, pytest-7.1.2, pluggy-1.0.0
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 2 items

test_demo.py Fx                                                                                                                                                   [100%]

=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________________ test_01 ________________________________________________________________________________
[XPASS(strict)]
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_01
===================================================================== 1 failed, 1 xfailed in 0.08s =====================================================================

前面已经提过,xfail的主要作用是在功能尚未支持的时候,暂时将脚本标记为xfail,当到了后期功能已经支持了,那么需要放开这些标记,当然可以通过修改脚本,将这些标记装饰器代码注释或者删除,此外pytest还提供了一种更为便捷的方式,即不需要注释或者删除原有的标记代码,即可执行,此时只需要在pytest命令中加上 –runxfail 参数即可。下面演示如下代码:

import pytest

@pytest.mark.xfail(run=True)
def test_01():
    print("\n in test_01...")

@pytest.mark.xfailj(run=False)
def test_02():
    print("\n in test_02...")

@pytest.mark.xfail
def test_03():
    print("\n in test_03...")

按照前面xfail的分析,test_02是不会执行的,而且会有两个被标记为xpass一个被标记为xfail,这里加上 –runxfail 参数,执行结果如下,很显然,此时好像没有xfail标记一样,完全按照普通的测试脚本执行了。

$ pytest --runxfail
========================================================================= test session starts ==========================================================================
rootdir: D:\redrose2100-book\ebooks\Pytest企业级应用实战\src
collected 3 items

test_demo.py ...                                                                                                                                                  [100%]

=========================================================================== warnings summary ===========================================================================
test_demo.py:7
  D:\redrose2100-book\ebooks\Pytest企业级应用实战\src\test_demo.py:7: PytestUnknownMarkWarning: Unknown pytest.mark.xfailj - is this a typo?  You can register custom mar
ks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    @pytest.mark.xfailj(run=False)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
===================================================================== 3 passed, 1 warning in 0.02s =====================================================================
.
 in test_02...

.
 in test_03...

.

=========================================================================== warnings summary ===========================================================================
test_demo.py:7
  D:\redrose2100-book\ebooks\Pytest企业级应用实战\src\test_demo.py:7: PytestUnknownMarkWarning: Unknown pytest.mark.xfailj - is this a typo?  You can register custom mar
ks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
    @pytest.mark.xfailj(run=False)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
===================================================================== 3 passed, 1 warning in 0.02s =====================================================================

Original: https://blog.csdn.net/redrose2100/article/details/122132648
Author: redrose2100
Title: Pytest内置标签xfail的用法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/773345/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球