Pytest精通指南(16)利用skip、skipif跳过用例执行

46 篇文章 2 订阅
32 篇文章 3 订阅


请添加图片描述

前言

skip:

  • skip用于无条件地跳过测试用例,无论测试环境的状态或条件如何。
  • 通常用于那些在任何情况下都不应该执行的测试用例,比如因为测试环境受限或特定条件下不需要执行。
  • 使用skip可以明确地指示某些测试用例不被执行,而不是因为它们失败而被标记为失败。

skipif:

  • skipif用于根据特定条件跳过测试用例。
  • 它允许定义一个条件表达式,当该表达式为真时,相应的测试用例会被跳过。
  • 这在功能未开发完成或某些用例在特定环境下无法运行时非常有用。通过使用skipif,可以避免在不满足测试条件的情况下执行这些用例,从而避免不必要的错误或失败。

补充描述:

  • skipskipif都是pytest框架提供的装饰器,用于控制测试用例的执行。
  • 使用skip时,不需要提供任何条件,它会无条件地跳过相应的测试用例。
  • 使用skipif时,需要提供一个可评估为TrueFalse的条件表达式。
  • 如果条件为真,则跳过测试用例;如果条件为假,则执行测试用例。
  • 这两个装饰器都提供了注释或说明来解释为什么跳过测试用例,这对于理解测试策略和测试结果非常有帮助。

总结来说,skip用于无条件跳过测试用例,而skipif则根据特定条件来决定是否跳过测试用例。

skip源码分析

这段代码是pytest框架内部的一部分,用于处理测试用例的跳过。

它定义了一个特殊的装饰器类_SkipMarkDecorator,这个类继承自MarkDecorator,并覆盖了其__call__方法以处理跳过的逻辑。

通过使用@overload装饰器,它提供了两种调用方式:

  • 一种是直接标记一个可标记的对象,
  • 另一种是提供一个跳过的原因并返回一个可以用于进一步操作的MarkDecorator实例。

结论:

  • 方法:skip(reason=None)
  • 参数:可选参数reason,用于标注跳过的原因,会在测试结果中显示
  • 使用方法:@pytest.mark.skip(reason="xxx")
    class _SkipMarkDecorator(MarkDecorator):
        @overload  # type: ignore[override,misc,no-overload-impl]
        def __call__(self, arg: Markable) -> Markable:
            ...

        @overload
        def __call__(self, reason: str = ...) -> "MarkDecorator":
            ...

skip装饰方法

示例代码

import pytest


# 使用skip装饰器跳过测试
@pytest.mark.skip(reason="测试skip强制跳过该测试用例执行")
def test_case_01():
    print("测试skip强制跳过该测试用例执行")
    assert 1 == 1

执行效果

请添加图片描述

skip装饰类

示例代码

import pytest


# 使用skip装饰器跳过测试
@pytest.mark.skip(reason="测试skip强制跳过该测试用例执行")
def test_case_01():
    print("测试skip强制跳过该测试用例执行")
    assert 1 == 1


@pytest.mark.skip(reason="测试skip强制跳过该类中的所有测试用例执行")
class TestClassDemo1:
    print("进入类内部")

    def test_case_02(self):
        print("测试skip强制跳过 test_case_02 执行")
        assert 1 == 1

    def test_case_03(self):
        print("测试skip强制跳过 test_case_03 执行")
        assert 1 == 1

执行结果

请添加图片描述

skip装饰模块

示例代码

import pytest

pytestmark = pytest.mark.skip(reason="跳过该模块中所有的测试用例函数")


# 使用skip装饰器跳过测试
# @pytest.mark.skip(reason="测试skip强制跳过该测试用例执行")
def test_case_01():
    print("测试skip强制跳过该测试用例执行")
    assert 1 == 1


# @pytest.mark.skip(reason="测试skip强制跳过该类中的所有测试用例执行")
class TestClassDemo1:
    print("进入类内部")

    def test_case_02(self):
        print("测试skip强制跳过 test_case_02 执行")
        assert 1 == 1

    def test_case_03(self):
        print("测试skip强制跳过 test_case_03 执行")
        assert 1 == 1

执行结果

请添加图片描述

skipif源码分析

在这段源码中,定义了一个名为_SkipifMarkDecorator的类,它继承自MarkDecorator。这个类似乎是用来处理条件性跳过测试用例的装饰器;意味着它可能是用于标记或修改测试行为的装饰器,特别是在满足某些条件时跳过测试。

在这个方法中,_SkipifMarkDecorator接收两个参数:condition*conditions,以及一个可选的reason参数。

  • condition: 这是一个位置参数,可以是一个字符串或一个布尔值。如果它是一个字符串,可能是一个条件表达式;如果是一个布尔值,它直接决定了是否跳过测试。
  • *conditions: 这是一个可变位置参数,意味着你可以传入任意数量的条件。这些条件可能是额外的字符串或布尔值,用于进一步定义何时跳过测试。
  • reason: 这是一个关键字参数,用于提供跳过测试的原因。这个信息通常用于在测试报告中显示,帮助开发者理解为什么测试被跳过。
    class _SkipifMarkDecorator(MarkDecorator):
        def __call__(  # type: ignore[override]
            self,
            condition: Union[str, bool] = ...,
            *conditions: Union[str, bool],
            reason: str = ...,
        ) -> MarkDecorator:
            ...

skipif装饰方法

示例代码

import pytest


@pytest.mark.skipif(condition=True, reason="测试skipif条件成立时跳过该测试用例执行")
def test_case_01():
    print("测试skipif条件成立时跳过 test_case_01 ")
    assert 1 == 1


@pytest.mark.skipif(condition=False, reason="测试skipif条件成立时跳过该测试用例执行")
def test_case_02():
    print("测试skipif条件成立时跳过 test_case_02")
    assert 1 == 1


@pytest.fixture
def data():
    return "hello"


# 定义一个函数,该函数返回是否应该跳过测试的条件
def should_skip_test():
    # 获取 data fixture 的值
    value = data()
    # 根据 value 的值决定是否跳过测试
    return value.startswith("h")


# @pytest.mark.skipif(condition=data().startswith("h"), reason="测试skipif条件成立时跳过该测试用例执行")
@pytest.mark.skipif(condition=should_skip_test, reason="测试skipif条件成立时跳过该测试用例执行")
def test_case_03():
    print("测试skipif条件成立时跳过 test_case_03")
    assert 1 == 1

执行结果

请添加图片描述

skipif装饰类

示例代码

import pytest


@pytest.mark.skipif(condition=True, reason="测试skipif条件成立时跳过该测试用例执行")
class TestClassDemo2:
    print("进入类的内部")

    def test_case_01(self):
        print("测试skipif条件成立时跳过 test_case_01 ")
        assert 1 == 1

    def test_case_02(self):
        print("测试skipif条件成立时跳过 test_case_02")
        assert 1 == 1

    def test_case_03(self):
        print("测试skipif条件成立时跳过 test_case_03")
        assert 1 == 1

执行结果

请添加图片描述

skipif装饰模块

示例代码

import sys

import pytest

pytestmark = pytest.mark.skipif(sys.platform == "darwin", reason="Mac系统中跳过该模块中的所有测试用例")
print("进入模块的内部")


# @pytest.mark.skipif(condition=True, reason="测试skipif条件成立时跳过该测试用例执行")
class TestClassDemo2:
    print("进入类的内部")

    def test_case_01(self):
        print("测试skipif条件成立时跳过 test_case_01 ")
        assert 1 == 1

    def test_case_02(self):
        print("测试skipif条件成立时跳过 test_case_02")
        assert 1 == 1

    def test_case_03(self):
        print("测试skipif条件成立时跳过 test_case_03")
        assert 1 == 1

执行结果

请添加图片描述

拓展-用例内部跳过执行

示例代码

import pytest
import platform


def test_case_01():
    print("进入test_case_01函数")
    if platform.system() == "Darwin":
        print("进入if判断")
        pytest.skip(reason="Darwin系统下跳过执行")
        print("Darwin系统下跳过执行")
    else:
        print("执行成功")

执行结果

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

需要休息的KK.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值