一、前言

  • pytest.mark.skip 可以标记无法在某些平台上运行的测试功能,或者您希望失败的测试功能

  • 希望满足某些条件才执行某些测试用例,否则pytest会跳过运行该测试用例

  • 实际常见场景:跳过非Windows平台上的仅Windows测试,或者跳过依赖于当前不可用的外部资源(例如数据库)的测试

二、skip介绍及运用

  1. skip跳过成功,标识为s

  2. pytest.main(['-rs','test01.py']) 用-rs执行,跳过原因才会显示SKIPPED

  3. skip跳过,无条件和原因@pytest.mark.skipif()

  4. skip跳过,无需满足条件true、有跳过原因@pytest.mark.skipif(reason='无条件,只有跳过原因')

  5. skip跳过,需满足条件true、且有跳过原因@pytest.mark.skipif(condition,reason='跳过原因')

  6. skip赋值变量,多处调用skipif_mark=pytest.mark.skipif(condition,reason='skip赋值给变量,可多处调用')

三、跳过测试类

@pytest.mark.skip()@pytest.mark.skipif()两个标签,用他们装饰测试类

skip跳过类

#skip跳过类

import pytest


@pytest.mark.skip(reason='跳过Test类,会跳过类中所有方法')
class Test(object):
    def test_one(self):
        assert 1+1 == 2

    def test_two(self):
        print('test_02')
        assert 1+1 == 3


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
    
# 输出

test_skip.py::Test::test_two 

============================= 2 skipped in 0.01s ==============================

Process finished with exit code 0
SKIPPED (跳过Test类,会跳过类中所有方法)    [ 50%]
Skipped: 跳过Test类,会跳过类中所有方法
SKIPPED (跳过Test类,会跳过类中所有方法)    [100%]
Skipped: 跳过Test类,会跳过类中所有方法

skip满足条件,skip跳过类

# skip满足条件,skip跳过类
import pytest


@pytest.mark.skipif(1 == 1, reason='跳过Test类,会跳过类中所有方法')
class Test(object):
    def test_one(self):
        assert 1+1 == 1

    def test_two(self):
        print('test_02')
        assert 1+1 == 2


if __name__ == '__main__':
    pytest.main(['-rs', 'test01.py'])

    
 # 输出
============================= 2 skipped in 0.02s ==============================

Process finished with exit code 0
SKIPPED (跳过Test类,会跳过类中所有方法)    [ 50%]
Skipped: 跳过Test类,会跳过类中所有方法
SKIPPED (跳过Test类,会跳过类中所有方法)    [100%]
Skipped: 跳过Test类,会跳过类中所有方法

四、跳过方法或测试用例

我们想要某个方法或跳过某条用例,在方法上加以下3种都可以

  1. @pytest.mark.skip() 跳过方法或用例,未备注原因

  2. @pytest.mark.skip(reason='跳过一个方法或一个测试用例') 跳过方法或用例,备注了原因

  3. @pytest.mark.skipif(1==1,reason='跳过一个方法或一个测试用例') 当条件满足,跳过方法或用例,备注了原因

跳过方法或用例,未备注原因

# 跳过方法或用例,未备注原因
import pytest


class Test(object):

    def test_one(self):
        assert 1+1 == 2

    @pytest.mark.skip()
    def test_two(self):
        print('test_02')
        assert 1+1 == 1


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
# 输出

============================= test session starts =============================
collecting ... collected 2 items

test_skip.py::Test::test_one 
test_skip.py::Test::test_two 

======================== 1 passed, 1 skipped in 0.01s =========================

Process finished with exit code 0
PASSED                                      [ 50%]SKIPPED (unconditional skip)                [100%]
Skipped: unconditional skip


跳过方法或用例,备注了原因

# 跳过方法或用例,备注了原因
import pytest


class Test(object):

    def test_one(self):
        assert 1+1 == 2

    @pytest.mark.skip(reason='跳过一个方法或一个测试用例')
    def test_two(self):
        print('test_02')
        assert 1+1 == 1


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])


# 输出

============================= test session starts =============================
collecting ... collected 2 items

test_skip.py::Test::test_one PASSED                                      [ 50%]
test_skip.py::Test::test_two SKIPPED (跳过一个方法或一个测试用例)        [100%]
Skipped: 跳过一个方法或一个测试用例


======================== 1 passed, 1 skipped in 0.01s =========================

当条件满足,跳过方法或用例,备注了原因

# 当条件满足,跳过方法或用例,备注了原因
import pytest


class Test(object):

    def test_one(self):
        assert 1 + 1 == 2

    @pytest.mark.skipif(1 == 1, reason='跳过一个方法或一个测试用例')
    def test_two(self):
        print('test_02')
        assert 1 + 1 == 1


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
# 输出

============================= test session starts =============================
collecting ... collected 2 items

test_skip.py::Test::test_one PASSED                                      [ 50%]
test_skip.py::Test::test_two SKIPPED (跳过一个方法或一个测试用例)        [100%]
Skipped: 跳过一个方法或一个测试用例

======================== 1 passed, 1 skipped in 0.02s =========================

知识点

  • @pytest.mark.skip 可以加在函数上,类上,类方法上

  • 如果加在类上面,类里面的所有测试用例都不会执行

五、多个skip时,满足1个条件即跳过

我们在类和方法上分别加了skip,类中满足条件,方法中未满足条件,所以生效类中skip

# 类skip不满足,方法skip满足,跳过该方法
import pytest


@pytest.mark.skipif(1 == 2, reason='多个条件时,有1个条件满足就跳过(类)')
class Test(object):
    def test_one(self):
        assert 1+1 == 2

    @pytest.mark.skipif(1 == 1, reason='多个条件时,有1个条件满足就跳过(方法)')
    def test_two(self):
        print('test_02')
        assert 1+1 == 1


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
# 输出
    
======================== 1 passed, 1 skipped in 0.01s =========================

Process finished with exit code 0
PASSED                                      [ 50%]SKIPPED (多个条件时,有1个条件满足就跳...)  [100%]
Skipped: 多个条件时,有1个条件满足就跳过(方法)

或者:

# 类skip满足,方法skip不满足,跳过该类所有的方法

import pytest


@pytest.mark.skipif(1 == 1, reason='多个条件时,有1个条件满足就跳过(类)')
class Test(object):
    def test_one(self):
        assert 1+1 == 2

    @pytest.mark.skipif(1 == 2, reason='多个条件时,有1个条件满足就跳过(方法)')
    def test_two(self):
        print('test_02')
        assert 1+1 == 1


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
# 输出

test_skip.py::Test::test_two SKIPPED (多个条件时,有1个条件满足就跳...)  [100%]
Skipped: 多个条件时,有1个条件满足就跳过(类)


============================= 2 skipped in 0.01s ==============================

六、skip赋值给变量,可多处调用

无论是@pytest.mark.skip()标签还是@pytest.mark.skipif()标签,如果你想在多个测试方法上装饰,依次写起来很麻烦的话,你可以选择定义个变量让它等于标签,然后在装饰的时候用该变量代替标签。这种方法,你还可以通过在其他模块中导入的变量的方式,在其他模块中共享标签;如果可以这样的话,我们为什么不新建一个模块用来存放标签呢?这样是不是又方便了许多。

赋值:skipmark=pytest.mark.skipif(1==1,reason='skip赋值给变量,可多处调用')

调用:@skipmark

import pytest

skipif_mark = pytest.mark.skipif(1 == 1, reason='skip赋值给变量,可多处调用')


class Test(object):
    def test_one(self):
        assert 1 + 1 == 2

    @skipif_mark
    def test_two(self):
        print('test_02')
        assert 1 + 1 == 1


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
# 输出

======================== 1 passed, 1 skipped in 0.01s =========================

Process finished with exit code 0
PASSED                                      [ 50%]SKIPPED (skip赋值给变量,可多处调用)        [100%]
Skipped: skip赋值给变量,可多处调用

七、pytest.skip()方法内跳过

除了通过使用标签的方式,还可以在测试用例中调用pytest.skip()方法来实现跳过,可以选择传入msg参数来说明跳过原因;如果想要通过判断是否跳过,可以写在if判断里(_)

import sys
import pytest

if sys.platform.startswith("win"):
    pytest.skip("skipping windows-only tests", allow_module_level=True)


@pytest.fixture(autouse=True)
def login():
    print("====登录====")


def test_case01():
    print("我是测试用例11111")


if __name__ == '__main__':
    pytest.main(['-rs', 'test_skip.py'])
    
# 输出

============================= test session starts =============================
collecting ... 
Skipped: skipping windows-only tests
collected 0 items / 1 skipped

============================= 1 skipped in 0.01s ==============================

pytest.skip(msg="",allow_module_level=False)

当 allow_module_level=True 时,可以设置在模块级别跳过整个模块

补充一个@pytest.mark.dependency 一个装饰器

@pytest.mark.dependency 是 Pytest 中的一个装饰器,用于标记测试函数之间的依赖关系。具体而言,它可以指定一个测试函数需要依赖于另一个测试函数执行成功后才能执行。

使用 @pytest.mark.dependency 的语法如下:

import pytest

@pytest.mark.dependency(name='test_b')
def test_b():
    assert True

@pytest.mark.dependency(depends=['test_b'])
def test_a():
    assert True

在上面的示例中,我们定义了两个测试函数 test_atest_b。其中,test_a 依赖于 test_b 执行成功后才能执行,因此我们在 test_a 的定义中使用了 @pytest.mark.dependency(depends=['test_b']) 的方式来标记它的依赖关系。

另外,为了让 Pytest 能够正确识别 test_b 这个依赖项,我们还需要在 test_b 的定义中使用 @pytest.mark.dependency(name='test_b') 的方式来为其指定一个名称。

需要注意的是,使用 @pytest.mark.dependency 标记测试函数之间的依赖关系可能会导致测试套件运行的顺序变得不稳定。如果测试函数之间没有明显的依赖关系,最好不要使用这个装饰器。