如何使用Pytest跳过部分测试用例

目录

面向跨平台开发的工具库会有部分代码与操作系统相关,比如 Linux 中使用 Shell 脚本,而在 Windows 中则使用 Powershell 脚本。 为 Shell 脚本功能编写的单元测试无需在 Windows 环境中运行,因此就需要根据操作系统自动跳过某些测试。

本文介绍如何在 Pytest 中跳过指定的测试用例。

测试文件

在目录 test_all 中创建两个简单的测试文件:

test_bar.py

def test_bar_one():
    assert 1 == 1


def test_bar_two():
    assert 2 == 2

test_foo.py

def test_foo_one():
    assert 1 == 1


def test_foo_two():
    assert 2 == 2

运行目录 test_all 下的所有测试,测试结果如下

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

test_bar.py::test_bar_one PASSED                                         [ 25%]
test_bar.py::test_bar_two PASSED                                         [ 50%]
test_foo.py::test_foo_one PASSED                                         [ 75%]
test_foo.py::test_foo_two PASSED                                         [100%]

============================== 4 passed in 0.03s ==============================

跳过测试

pytest.mark.skip 用于跳过测试。

可以作为测试函数的装饰器,跳过该函数。 按如下代码修改 test_foo.py 文件,会跳过 test_foo_one 函数:

import pytest

@pytest.mark.skip(reason="no way of currently testing this")
def test_foo_one():
    assert 1 == 1

def test_foo_two():
    assert 2 == 2

可以修改全局变量 pytestmark,跳过整个文件中的所有测试函数。 按如下代码修改 test_bar.py 文件,会跳过文件中的所有测试函数:

import pytest

pytestmark = pytest.mark.skip("all tests still WIP")

def test_bar_one():
    assert 1 == 1

def test_bar_two():
    assert 2 == 2

运行测试,结果如下:

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

test_bar.py::test_bar_one SKIPPED (all tests still WIP)                  [ 25%]
Skipped: all tests still WIP

test_bar.py::test_bar_two SKIPPED (all tests still WIP)                  [ 50%]
Skipped: all tests still WIP

test_foo.py::test_foo_one SKIPPED (no way of currently testing this)     [ 75%]
Skipped: no way of currently testing this

test_foo.py::test_foo_two PASSED                                         [100%]

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

按条件跳过测试

pytest.mark.skipif 用于按条件跳过测试,第一个参数为判断条件,只有在条件满足的情况下才跳过测试。

可以作为测试函数的装饰器,按条件跳过该函数。 按如下代码修改 test_foo.py 文件,在 Windows 下运行 (sys.platform == "win32") 时会跳过 test_foo_one 函数:

import sys
import pytest

@pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")
def test_foo_one():
    assert 1 == 1

def test_foo_two():
    assert 2 == 2

可以修改全局变量 pytestmark,按条件跳过整个文件中的所有测试函数。 按如下代码修改 test_bar.py 文件,在 Windows 下运行 (sys.platform == "win32") 时会跳过文件中的所有测试函数:

import sys
import pytest

pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="tests for linux only")

def test_bar_one():
    assert 1 == 1

def test_bar_two():
    assert 2 == 2

在 Linux 下运行测试,所有测试均运行:

============================= test session starts ==============================
collected 4 items                                                              

test_bar.py::test_bar_one PASSED                                         [ 25%]
test_bar.py::test_bar_two PASSED                                         [ 50%]
test_foo.py::test_foo_one PASSED                                         [ 75%]
test_foo.py::test_foo_two PASSED                                         [100%]

========================= 4 passed, 1 warning in 0.07s =========================

在 Windows 下运行测试,有三个测试被跳过:

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

test_bar.py::test_bar_one SKIPPED (tests for linux only)                 [ 25%]
Skipped: tests for linux only

test_bar.py::test_bar_two SKIPPED (tests for linux only)                 [ 50%]
Skipped: tests for linux only

test_foo.py::test_foo_one SKIPPED (does not run on windows)              [ 75%]
Skipped: does not run on windows

test_foo.py::test_foo_two PASSED                                         [100%]

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

总结

根据 Pytest 文档 How to use skip and xfail to deal with tests that cannot succeed,有3种方法可以在不同情况下跳过模块中的测试:

  1. 无条件跳过模块中的所有测试
pytestmark = pytest.mark.skip("all tests still WIP")
  1. 根据条件跳过模块中的所有测试
pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="tests for linux only")
  1. 如果某个导入包缺失,则跳过模块中的所有测试
pexpect = pytest.importorskip("pexpect")

本文介绍了前两种方式。

参考

Pytest 文档:How to use skip and xfail to deal with tests that cannot succeed