有时候,为了满足某些场景的需要,我们知道有些测试函数在这时候肯定不能执行,或者执行了也会失败。那么我们

可以选择去跳过这个测试函数,这样也就不会影响整体的测试函数运行效果,不至于在你运行的众多绿色通过的测试

用例中,给你加点红色的failed或者error。

举个例子,有些测试函数只能在windows上运行,那么换了个Linux平台就不可以,就需要跳过这个测试函数。再比如,

有些测试用例会有一些外部资源的依赖,像数据库,那么当数据库资源不可用的时候,也需要去跳过这个测试函数。

在pytest中提供了这样一个机制来跳过测试函数。

一、skip

用法很简单,只要在需要跳过的测试函数上面安上@pytest.mark.skip()即可。可以传递一个参数reason,填写

跳过的理由,不填也可以。

@pytest.mark.skip(reason="没啥理由,就不想执行")
def test_the_unknown():
...

运行结果:

test_skipif.py                                                          [100%]

============================= 1 skipped in 0.02s ==============================s
Skipped: 没啥理由,就不想执行 Process finished with exit code 0

可以看到,这个测试用例被成功跳过,并且还有reason的输出。不过pytest默认情况下,不会显示跳过的测试函数的详细信息,

避免输出与正常的混在一起,太乱。

二、pytest.skip(reason)

1. 在测试函数或者fixture函数里使用

除了上述用法,还可以用pytest.skip(reason)函数,在测试函数中或者setup函数里进行跳过。比如,当有些参数不符合你

的预期,那么就跳过后面的执行。

上示例代码:

import pytest

@pytest.fixture()
def demo_fixture(request):
test_input = request.param
if test_input == 3:
pytest.skip("传入的值等于3就跳过执行") @pytest.mark.parametrize("demo_fixture", [1, 3], indirect=True)
def test_the_unknown3(demo_fixture):
... if __name__ == "__main__":
pytest.main(["-s", '-r' "test_skipif.py"])

在上述代码里,我在测试函数test_the_unknown3里做了一个参数化,并且在fixture函数demo_fixture拿到这个参数。

按理来说,参数化了1和3,所以测试函数会执行2次。

我在fixture函数里加了判断,当拿到的参数,等于3的时候,就跳过执行。所以最终的运行结果应该是,1执行,3跳过。

test_skipif.py                                                         [100%]

======================== 1 passed, 1 skipped in 0.09s =========================.s
Skipped: 传入的值等于3就跳过执行 Process finished with exit code 0

结果符合预期。

这个用法,刚好解决了我一个实际问题。

那就是别的小组有不少人写case用的测试数据,是会通过别的case或者别的接口调用后传递过来的,那么当这些依赖有问题的时候

case运行就会有问题,导致误报。如果使用pytest.skip(reason)这个函数,那么可以有效缓解case误报的问题。

2. allow_module_level=True跳过整个模块

如果你需要判断某些条件符合时候,就要整个模块都跳过,就可以加上这个参数allow_module_level=True

import pytest

a = 1

if a != 3:
pytest.skip("a不等于3就跳过整个文件模块", allow_module_level=True) @pytest.fixture()
def demo_fixture(request):
test_input = request.param
if test_input == 3:
pytest.skip("传入的值等于3就跳过") @pytest.mark.parametrize("demo_fixture", [1, 3], indirect=True)
def test_the_unknown1(demo_fixture):
... def test_the_unknown2():
... def test_the_unknown3():
...

运行一下:

============================= 1 skipped in 0.02s ==============================
Skipped: a不等于3就跳过整个文件模块 Process finished with exit code 0

三、skipif

1. skipif有条件的跳过

上面提到了在函数里写判断,当满足某个条件时通过pytest.skip函数来跳过,其实还可以直接用skipif,同样可以

达到有条件地跳过某些内容的目的。

import sys

@pytest.mark.skipif(sys.version_info < (4, 0), reason="版本4.0以下就跳过执行")
def test_function():
print(sys.version_info)

运行结果:

test_module1.py                                                         [100%]

============================= 1 skipped in 0.02s ==============================s
Skipped: 版本4.0以下就跳过执行 Process finished with exit code 0

2.模块之间共享skip标记

比如说,我现在有2个测试模块,分别是test_module1.pytest_module2.py

我在test_module1.py当中,定义一个skipif作为marker 共享,也就是not_equal_5

那么在test_module2.py当中导入这个marker,就可以直接使用了,看代码效果:

# content of test_module1.py
import pytest
import sys version_judge = pytest.mark.skipif(
sys.version_info < (4, 0), reason="版本4.0以下就跳过执行"
) @version_judge
def test_the_unknown2():
... if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])

test_module2.py中导入marker使用,运行后的预期结果,应该是test_the_unknown1跳过执行。

# content of test_module2.py
import pytest
from interface.demo.test_module1 import version_judge @version_judge
def test_the_unknown1():
... def test_the_unknown2():
... if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module2.py"])

运行下test_module2.py:

test_module2.py                                                        [100%]

======================== 1 passed, 1 skipped in 0.08s =========================s
Skipped: 版本4.0以下就跳过执行
.
Process finished with exit code 0

四、跳过类或模块下的所有测试函数

1. 跳过类下的所有测试函数

如果把skipif放在类上,这个类下面的所有测试函数都会跳过。

import pytest
import sys version_judge = pytest.mark.skipif(
sys.version_info < (4, 0), reason="版本4.0以下就跳过执行"
) @version_judge
class TestDemo(): def test_the_unknown2(self):
... def test_the_unknown3(self):
... def test_the_unknown1():
... if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])

运行结果,类TestDemo下的2个测试方法都会被跳过。

test_module1.py                                                       [100%]

======================== 1 passed, 2 skipped in 0.09s =========================s
Skipped: 版本4.0以下就跳过执行
s
Skipped: 版本4.0以下就跳过执行
.
Process finished with exit code 0

2.跳过模块下的所有测试函数

如果想跳过模块的所有测试函数,可以使用全局变量pytestmark:

import pytest
import sys pytestmark = pytest.mark.skipif(sys.version_info < (4, 0), reason="版本4.0以下就跳过执行") class TestDemo(): def test_the_unknown2(self):
... def test_the_unknown3(self):
... def test_the_unknown1():
... if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])

运行,模块下的3个测试都会被跳过

test_module1.py                                                       [100%]

============================= 3 skipped in 0.02s ==============================s
Skipped: 版本4.0以下就跳过执行
s
Skipped: 版本4.0以下就跳过执行
s
Skipped: 版本4.0以下就跳过执行 Process finished with exit code 0

另外,如果多个skipif装饰器应用于同一个测试函数,只要任何一个条件为真,该函数将被跳过。

五、跳过文件或目录

有时可能需要跳过一整个文件或目录。例如,有文件里的代码你不想去执行。在这种情况下,必须从pytest搜集到的集合中排除文件和目录。

有关更多信息,请参阅自定义测试集合,后续看情况单独分享。

六、导入依赖失败跳过

当有些依赖的包导入失败的时候,可以通过pytest.importorskip这个函数来跳过。同样,可以用在模块级别,fixture函数或者测试函数里。

import pytest

# docutils = pytest.importorskip("docutils")

class TestDemo():

    def test_the_unknown2(self):
... def test_the_unknown3(self):
pytest.importorskip("docutils") def test_the_unknown1():
... if __name__ == "__main__":
pytest.main(["-s", '-r' "test_module1.py"])

运行结果,应该是跳过一个,执行2个:

test_module1.py                                                       [100%]

======================== 2 passed, 1 skipped in 0.09s =========================.s
Skipped: could not import 'docutils': No module named 'docutils'
.
Process finished with exit code 0

代码里的docutils是一个第三方库,你也可以根据库的版本号跳过:

docutils = pytest.importorskip("docutils", minversion="0.3")

版本将从指定模块的__version__属性中读取,如果不符合条件,也会跳过。

七、总结

  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官方文档】解读Skipping test functions,跳过测试用例详解的更多相关文章

  1. webpack官方文档分析(三):Entry Points详解

    1.有很多种方法可以在webpack的配置中定义entry属性,为了解释为什么它对你有用,我们将展现有哪些方法可以配置entry属性. 2.单一条目语法 用法: entry: string|Array ...

  2. 【pytest官方文档】解读fixtures - 1.什么是fixtures

    在深入了解fixture之前,让我们先看看什么是测试. 一.测试的构成 其实说白了,测试就是在特定的环境.特定的场景下.执行特定的行为,然后确认结果与期望的是否一致. 就拿最常见的登录来说,完成一次正 ...

  3. 【pytest官方文档】解读fixtures - 2. fixtures的调用方式

    既然fixtures是给执行测试做准备工作的,那么pytest如何知道哪些测试函数 或者 fixtures要用到哪一个fixtures呢? 说白了,就是fixtures的调用. 一.测试函数声明传参请 ...

  4. 【pytest官方文档】解读fixtures - 3. fixtures调用别的fixtures、以及fixture的复用性

    pytest最大的优点之一就是它非常灵活. 它可以将复杂的测试需求简化为更简单和有组织的函数,然后这些函数可以根据自身的需求去依赖别的函数. fixtures可以调用别的fixtures正是灵活性的体 ...

  5. Cuda 9.2 CuDnn7.0 官方文档解读

    目录 Cuda 9.2 CuDnn7.0 官方文档解读 准备工作(下载) 显卡驱动重装 CUDA安装 系统要求 处理之前安装的cuda文件 下载的deb安装过程 下载的runfile的安装过程 安装完 ...

  6. 【pytest官方文档】解读- 插件开发之hooks 函数(钩子)

    上一节讲到如何安装和使用第三方插件,用法很简单.接下来解读下如何自己开发pytest插件. 但是,由于一个插件包含一个或多个钩子函数开发而来,所以在具体开发插件之前还需要先学习hooks函数. 一.什 ...

  7. 【pytest官方文档】解读fixtures - 8. yield和addfinalizer的区别(填坑)

    在上一章中,文末留下了一个坑待填补,疑问是这样的: 目前从官方文档中看到的是 We have to be careful though, because pytest will run that fi ...

  8. 【pytest官方文档】解读fixtures - 7. Teardown处理,yield和addfinalizer

    当我们运行测试函数时,我们希望确保测试函数在运行结束后,可以自己清理掉对环境的影响. 这样的话,它们就不会干扰任何其他的测试函数,更不会日积月累的留下越来越多的测试数据. 用过unittest的朋友相 ...

  9. 【pytest官方文档】解读fixtures - 10. fixture有效性、跨文件共享fixtures

    一.fixture有效性 fixture有效性,说白了就是fixture函数只有在它定义的使用范围内,才可以被请求到.比如,在类里面定义了一个fixture, 那么就只能是这个类中的测试函数才可以请求 ...

  10. 【pytest官方文档】解读- 开发可pip安装的第三方插件

    在上一篇的 hooks 函数分享中,开发了一个本地插件示例,其实已经算是在编写插件了.今天继续跟着官方文档学习更多知识点. 一个插件包含一个或多个钩子函数,pytest 正是通过调用各种钩子组成的插件 ...

随机推荐

  1. HTTP 协议中的并发限制及队首阻塞问题

    本文转载自HTTP 协议中的并发限制及队首阻塞问题 串行连接 HTTP/0.9 和早期的 HTTP/1.0 协议对 HTTP 请求处理是串行化的.假如一个页面包含 3 个样式文件,同属于一个协议.域名 ...

  2. Django模型层2

    目录 一.聚合查询 聚合函数 二.分组查询 利用group by进行分组查询 三.F与Q查询 1. F类 2. Q类 四.orm字段及参数 五.自定义char字段 六.orm中的事务操作 1. 什么是 ...

  3. C++构造函数的选择

    构造函数用来初始化类对象.构造函数有好几种,在编程时如何选择不同的构造函数呢?做个总结 一.默认构造函数 默认构造函数是在程序员没有声明任何构造函数的时,编译器为了初始化类对象自己进行的默认构造函数. ...

  4. 在Arch上使用Fcitx5

    目录 卸载Fcitx4 安装Fcitx5 配置 修改环境变量 系统登陆后默认启动Fcitx5输入法 配置主题 最终使用效果 参考文档 我是一个Arch+KDE的用户,所以下面的方法可能不适合所有的Li ...

  5. macOS网络安全审计

    nettop监听网络流量的方法 nettop是macOS系统自带的命令,命令功能能监听网络流量,如果你想查询一个恶意域名.ip和本机进程连接情况,那么可以试试nettop,就是展示方式不是太友好,需要 ...

  6. HDOJ-1540(线段树+较复杂的单点修改和区间查询)

    Tunnel Warfare HDOJ-1540 这题关于线段树的操作有一定的难度,需要较好的思维能力. 关于题目的详细解答已经在代码中体现了. #include<iostream> #i ...

  7. 日志文件迁移至OSS

    一台服务器在用阿里云ECS,因为穷,磁盘空间有限,服务器日志文件每天都在增长,需要定期清理释放磁盘空间,想到几种解决方案: 写任务定时备份到本地服务器 直接下载到本地用移动硬盘备份 备份到阿里云OSS ...

  8. mysql数据库的数据备份,以及开启日志

    导出数据: location代表需要保存的数据文件的位置,默认保存在 C:\ProgramData\MySQL\MySQL Server 5.7\Data(Windows10系统位置,其他系统位置自行 ...

  9. Solon 框架详解(九)- 渲染控制之定制统一的接口输出

    Springboot min -Solon 详解系列文章: Springboot mini - Solon详解(一)- 快速入门 Springboot mini - Solon详解(二)- Solon ...

  10. 1.认识numpy的数组

    认识ndarray --ndarray:用于存储单一数据类型的多维数组 ndarray基础属性的认识 import numpy as np #将numpy简写为np方便调用 1.通过以下实例来认识ar ...