pytest学习和使用10-Pytest中的测试用例如何跳过执行?

时间:2023-02-07 15:03:18

(10-Pytest中的测试用例如何跳过执行?)

1 引入

  • 有时候我们需要对某些指定的用例进行跳过,或者用例执行中进行跳过,在Unittest中我们使用skip()方法;
  • Pytest中如何使用呢?
  • Pytest中也提供了两种方式进行用例的跳过skip、skipif

2 Unittest中的用例跳过

# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_unittest_skip.py
# 作用:验证unittest的skip
# 博客:https://blog.csdn.net/NoamaNelson

import unittest

class TestCase(unittest.TestCase):
    def test_1(self):
        print("用例1")

    def test_2(self):
        print("用例2")

    @unittest.skip("该用例不执行,没用")
    def test_3(self):
        print("用例3")


if __name__ == '__main__':
    unittest.main()
======================== 2 passed, 1 skipped in 0.05s =========================

进程已结束,退出代码 0
PASSED                           [ 33%]用例1
PASSED                           [ 66%]用例2
SKIPPED (该用例不执行,没用)     [100%]
Skipped: 该用例不执行,没用

3 pytest.mark.skip

  • pytest.mark.skip 可标记无法运行的测试功能,或者您希望失败的测试功能;
  • 简单说就是跳过执行测试用例;
  • 可选参数reason:是跳过的原因,会在执行结果中打印;
  • 可以使用在函数上,类上,类方法上;
  • 使用在类上面,类里面的所有测试用例都不会执行;
  • 作用范围最小的是一个测试用例;
  • 这个功能和unittest基本是一样的。
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_skip.py
# 作用:验证pytest的skip功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest

@pytest.fixture(scope="module")
def start():
    print("打开浏览器,输入用户名和密码登陆")
    # yield
    # print("关闭浏览器")

def test_1(start):
    print("用例1......")

def test_2(start):
    print("用例2......")

@pytest.mark.skip(reason="用例3不用执行")
def test_3(start):
    print("用例3......")

class TestA():

    def test_4(self):
        print("用例4......")

    @pytest.mark.skip(reason="用例5不用执行")
    def test_5(self):
        print("用例5......")

@pytest.mark.skip(reason="该类中的用例不用执行")
class TestB():
    def test_6(self):
        print("用例6......")


if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_skip.py"])

test_pytest_skip.py::test_1              打开浏览器,输入用户名和密码登陆
PASSED                                   [ 16%]用例1......

test_pytest_skip.py::test_2 PASSED       [ 33%]用例2......

test_pytest_skip.py::test_3 SKIPPED      (用例3不用执行)  [ 50%]
                                          Skipped: 用例3不用执行

test_pytest_skip.py::TestA::test_4 PASSED  [ 66%]用例4......

test_pytest_skip.py::TestA::test_5 SKIPPED (用例5不用执行)  [ 83%]
                                            Skipped: 用例5不用执行

test_pytest_skip.py::TestB::test_6 SKIPPED (该类中的用例不用执行)   [100%]
                                            Skipped: 该类中的用例不用执行


======================== 3 passed, 3 skipped in 0.04s =========================

4 pytest.skip()

  • pytest.skip()不同于pytest.mark.skippytest.mark.skip是作用于整个测试用例;
  • pytest.skip()是测试用例执行期间强制跳过不再执行剩余内容;
  • Python中break 跳出循环类似,如下:
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_skip1.py
# 作用:验证pytest的skip()函数功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest
import time

@pytest.fixture()
def start():
    print("打开浏览器,输入用户名和密码登陆")
    yield
    print("关闭浏览器")

def test_1(start):
    print("用例1......")
    i = 1
    while True:
        print(time.time())
        i += 1
        if i == 6:
            pytest.skip("打印5次时间后,第六次不再打印了~")

if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_skip1.py"])

test_pytest_skip1.py::test_1 打开浏览器,输入用户名和密码登陆
SKIPPED (打印5次时间后,第六次不再打印了~)  [100%]用例1......
1668677189.0525532
1668677189.0525532
1668677189.0525532
1668677189.0525532
1668677189.0525532

Skipped: 打印5次时间后,第六次不再打印了~
关闭浏览器


============================= 1 skipped in 0.02s ==============================

  • pytest.skip(msg="",allow_module_level=True )时,设置在模块级别跳过整个模块,如下:
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_skip2.py
# 作用:验证pytest的skip()参数allow_module_level=True功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest
import time
import sys

if sys.platform.startswith("win"):
    pytest.skip("跳过Windows平台的用例", allow_module_level=True)

@pytest.fixture()
def start():
    print("打开浏览器,输入用户名和密码登陆")
    yield
    print("关闭浏览器")

def test_1(start):
    print("用例1......")
    i = 1
    while True:
        print(time.time())
        i += 1
        if i == 6:
            pytest.skip("打印5次时间后,第六次不再打印了~")


if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_skip2.py"])

collected 0 items / 1 skipped

============================= 1 skipped in 0.02s ==============================

5 pytest.mark.skipif()

  • 在条件满足时,跳过某些用例;
  • 参数为pytest.mark.skipif(condition, reason="")
  • condition需要返回True才会跳过。
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_skipif.py
# 作用:验证pytest的skipif()功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest
import time
import sys

@pytest.mark.skipif(sys.platform == "win32", reason="Windows平台不执行")
class TestA():
    @pytest.fixture()
    def start(self):
        print("打开浏览器,输入用户名和密码登陆")
        yield
        print("关闭浏览器")

    def test_1(self, start):
        print("用例1......")
        i = 1
        while True:
            print(time.time())
            i += 1
            if i == 6:
                pytest.skip("打印5次时间后,第六次不再打印了~")


if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_skipif.py"])

test_pytest_skipif.py::TestA::test_1 SKIPPED (Windows平台不执行)         [100%]
Skipped: Windows平台不执行


============================= 1 skipped in 0.02s ==============================

6 跳过标记

  • 简单理解为把pytest.mark.skippytest.mark.skipif 赋值给一个标记变量;
  • 不同模块之间共享这个标记变量;
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_skipif1.py
# 作用:验证pytest的skipif()功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest
import time
import sys

mark1 = pytest.mark.skipif(sys.platform == "win32", reason="Windows平台不执行")
mark2 = pytest.mark.skip("不用执行这个用例")

@mark1
class TestA():
    @pytest.fixture()
    def start(self):
        print("打开浏览器,输入用户名和密码登陆")
        yield
        print("关闭浏览器")

    def test_1(self, start):
        print("test case 1 ......")

@mark2
def test_2(self, start):
    print("test case 2 ......")


if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_skipif1.py"])

test_pytest_skipif1.py::TestA::test_1 SKIPPED (Windows平台不执行)        [ 50%]
Skipped: Windows平台不执行

test_pytest_skipif1.py::test_2 SKIPPED (不用执行这个用例)                [100%]
Skipped: 不用执行这个用例


============================= 2 skipped in 0.02s ==============================

7 pytest.importorskip

  • 参数为:( modname: str, minversion: Optional[str] = None, reason: Optional[str] = None )
参数 说明
modname 模块名
minversion 版本号
reason 原因
  • 作用为:如果缺少某些导入,则跳过模块中的所有测试;

  • pip list下,我们找一个存在的版本的包试试:

pytest学习和使用10-Pytest中的测试用例如何跳过执行?

  • 比如attrs,版本为20.3.0,代码如下:
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_importskip.py
# 作用:验证pytest的importskip功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest
import amqp

attrs = pytest.importorskip("attrs", minversion="20.3.0")
@attrs
def test_1():
    print("=====模块不存在")

def test_2():
    print("=====模块存在")

if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_importskip.py"])

Skipped: could not import 'attrs': No module named 'attrs'
collected 0 items / 1 skipped

============================= 1 skipped in 0.05s ==============================
  • 再比如sys,版本为1.1.1,引入包后,显示如下:
# -*- coding:utf-8 -*-
# 作者:NoamaNelson
# 日期:2022/11/17 
# 文件名称:test_pytest_importskip1.py
# 作用:验证pytest的importskip功能
# 博客:https://blog.csdn.net/NoamaNelson

import pytest
import sys

sys1 = pytest.importorskip("sys", minversion="1.1.1")

@sys1
def test_1():
    print(sys.platform)
    print("=====模块存在")


if __name__ == '__main__':
    pytest.main(["-s", "test_pytest_importskip1.py"])

Skipped: module 'sys' has __version__ None, required is: '1.1.1'
collected 0 items / 1 skipped

============================= 1 skipped in 0.03s ==============================