一、显示xpass、xfail、skip用例的简要信息
pytest -rxXs 命令可以显示skip,xfail,xpass用例的简要信息
test_demo.py代码如下:
import pytest
@pytest.mark.skip()
def test_func1():
pass
@pytest.mark.xfail()
def test_func2():
pass
@pytest.mark.skip()
def test_func3():
pass
def test_func4():
pass
执行结果如下:
$ pytest -rxXs
========================================================================= 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 4 items
test_demo.py sXs. [100%]
======================================================================= short test summary info ========================================================================
XPASS test_demo.py::test_func2
SKIPPED [1] test_demo.py:3: unconditional skip
SKIPPED [1] test_demo.py:11: unconditional skip
=============================================================== 1 passed, 2 skipped, 1 xpassed in 0.03s ================================================================
二、skip的用法
(1)跳过函数
test_demo.py代码如下:
import pytest
@pytest.mark.skip(reason="no way of currently testing this")
def test_the_unknown():
pass
执行结果如下:
$ 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 s [100%]
========================================================================== 1 skipped in 0.03s ==========================================================================
(2)在测试函数体内比如设置跳过条件
test_demo.py代码如下,比如windows上个不执行
import pytest
import platform
def test_the_unknown():
if platform.system()=="Windows":
pytest.skip("不支持windows")
执行结果如下:
$ 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 s [100%]
========================================================================== 1 skipped in 0.03s ==========================================================================
(3)跳过整个测试文件,即模块,比如当前文件的测试不支持windows,可以参考如下方式配置
test_demo.py代码如下:
import sys
import pytest
if sys.platform.startswith("win"):
pytest.skip("不支持windows", allow_module_level=True)
def test_func1():
assert 1==1
def test_func2():
assert 1==1
def test_func3():
assert 1==1
执行结果如下,可以看出,整个文件中的测试函数均未执行
$ 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 0 items / 1 skipped
========================================================================== 1 skipped in 0.02s ==========================================================================
三、skipif的用法
(1)skip如果是有条件的跳过需要在测试函数中写if语句,skipif则可以直接使用装饰器的方式跳过
test_demo.py代码如下:
import pytest
import platform
@pytest.mark.skipif(platform.system()=="Windows",reason="不支持window平台")
def test_the_unknown():
assert 1==1
执行结果如下:
$ 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 s [100%]
========================================================================== 1 skipped in 0.02s ==========================================================================
(2)可以共享定义好的skipif语句块
如下,在test_demo.py中定义了skip_windows,可以在当前模块使用,也可以在其他模块导入使用
目录结构如下:
tests
|----__init__.py
|----test_demo.py
|----test_demo2.py
其中test_demo.py代码如下:
import pytest
import platform
skip_windows=pytest.mark.skipif(platform.system()=="Windows",reason="不支持window平台")
@skip_windows
def test_the_unknown():
assert 1==1
test_demo2.py代码如下:
from tests.test_demo import skip_windows
@skip_windows
def test_the_unknown():
assert 1==1
执行结果如下:
$ 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 2 items
test_demo.py s [ 50%]
test_demo2.py s [100%]
========================================================================== 2 skipped in 0.03s ==========================================================================
(3)跳过整个测试类
test_demo.py代码如下
import pytest
import platform
@pytest.mark.skipif(platform.system()=="Windows",reason="不支持window平台")
class TestDemo():
def test_01(self):
assert 1==1
def test_02(self):
assert 2==2
执行结构如下:
$ 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 2 items
test_demo.py ss [100%]
========================================================================== 2 skipped in 0.03s ==========================================================================
(4)跳过整个测试文件
test_demo.py代码如下:
import pytest
import platform
pytestmark = pytest.mark.skipif(platform.system()=="Windows",reason="不支持window平台")
def test_01():
assert 1==1
def test_02():
assert 2==2
执行结果如下:
$ 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 2 items
test_demo.py ss [100%]
========================================================================== 2 skipped in 0.03s ==========================================================================
四、当导入模块失败时跳过
当在导入模块不存在或者报错时,使用如下语句可以跳过,注意需要将此语句放在导入语句的上面
test_demo.py代码如下,这里假设当前环境没有安装TensorFlow,这里导入会失败
import pytest
pexpect = pytest.importorskip("pexpect")
import tensorflow
def test_01():
assert 1==1
def test_02():
assert 2==2
执行结果如下,会直接跳过,而不会报导入错误
$ 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 0 items / 1 skipped
========================================================================== 1 skipped in 0.02s ==========================================================================
五、xfail的用法
(1)xfail标记失败
test_demo.py代码如下:
import pytest
@pytest.mark.xfail
def test_01():
assert 1==1
执行结果如下:
$ 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 ==========================================================================
(2)根据具体条件标记失败
test_demo.py代码如下:
import pytest
import platform
def test_01():
if platform.system() == "Windows":
pytest.xfail("不支持windows系统")
执行结果如下:
$ 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 xfailed in 0.06s ==========================================================================
使用pytest.mark.xfail也可以设置根据具体条件标记失败,此时需要额外增加reason参数
test_demo.py代码如下:
import pytest
import platform
@pytest.mark.xfail(platform.system() == "Windows",reason="不支持windows系统")
def test_01():
assert 1==1
执行结果如下:
$ 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 ==========================================================================
(3)pytest.mark.xfail也可以只设置reason参数
test_demo.py代码如下:
import pytest
@pytest.mark.xfail(reason="不支持windows系统")
def test_01():
assert 1==1
执行结果如下:
$ 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.02s ==========================================================================
(4)通过run参数可以设置是否执行
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 -s
========================================================================= 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 2 items
test_demo.py x
in test_02...
X
==================================================================== 1 xfailed, 1 xpassed in 0.09s =====================================================================
(5)xpass和xfail都不会显示测试失败,如果希望显示测试失败可以通过设置strict=True
test_demo.py代码如下:
import pytest
@pytest.mark.xfail(strict=True)
def test_01():
assert 1==1
执行结果如下:
$ 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 F [100%]
=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________________ test_01 ________________________________________________________________________________
[XPASS(strict)]
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_01
========================================================================== 1 failed in 0.03s ===========================================================================
也可以在pytest.ini中设置,如pytest.ini设置如下:
[pytest]
xfail_strict=true
此时test_demo.py代码如下:
import pytest
@pytest.mark.xfail()
def test_01():
assert 1==1
执行结果如下:
$ 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 F [100%]
=============================================================================== FAILURES ===============================================================================
_______________________________________________________________________________ test_01 ________________________________________________________________________________
[XPASS(strict)]
======================================================================= short test summary info ========================================================================
FAILED test_demo.py::test_01
========================================================================== 1 failed in 0.03s ===========================================================================
(6)当标记了xfail之后,若想使xfail失效,则可以在命令行使用 pytest --runxfail 即可
test_demo.py代码如下:
import pytest
@pytest.mark.xfail()
def test_01():
assert 1==1
执行结果如下:
$ pytest --runxfail
========================================================================= 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 . [100%]
========================================================================== 1 passed in 0.02s ===========================================================================
六、在参数化中使用xfail和skip
test_demo.py代码如下:
import sys
import pytest
@pytest.mark.parametrize(
("n", "expected"),
[
(1, 2),
pytest.param(1, 0, marks=pytest.mark.xfail),
pytest.param(1, 3, marks=pytest.mark.xfail(reason="some bug")),
(2, 3),
(3, 4),
(4, 5),
pytest.param(
10, 11, marks=pytest.mark.skipif(sys.version_info >= (3, 0), reason="py2k")
),
],
)
def test_increment(n, expected):
assert n + 1 == expected
执行结果如下:
$ 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 7 items
test_demo.py .xx...s [100%]
=============================================================== 4 passed, 1 skipped, 2 xfailed in 0.07s ================================================================