Pytest官方教程-12-skip及xfail: 处理不能成功的测试用例

目录:

  1. 安装及入门
  2. 使用和调用方法
  3. 原有TestSuite使用方法
  4. 断言的编写和报告
  5. Pytest fixtures:清晰 模块化 易扩展
  6. 使用Marks标记测试用例
  7. Monkeypatching/对模块和环境进行Mock
  8. 使用tmp目录和文件
  9. 捕获stdout及stderr输出
  10. 捕获警告信息
  11. 模块及测试文件中集成doctest测试
  12. skip及xfail: 处理不能成功的测试用例
  13. Fixture方法及测试用例的参数化
  14. 缓存: 使用跨执行状态
  15. unittest.TestCase支持
  16. 运行Nose用例
  17. 经典xUnit风格的setup/teardown
  18. 安装和使用插件
  19. 插件编写
  20. 编写钩子(hook)方法
  21. 运行日志
  22. API参考
    1. 方法(Functions)
    2. 标记(Marks)
    3. 钩子(Hooks)
    4. 装置(Fixtures)
    5. 对象(Objects)
    6. 特殊变量(Special Variables)
    7. 环境变量(Environment Variables)
    8. 配置选项(Configuration Options)
  23. 优质集成实践
  24. 片状测试
  25. Pytest导入机制及sys.path/PYTHONPATH
  26. 配置选项
  27. 示例及自定义技巧
  28. Bash自动补全设置

skip及xfail: 处理不能成功的测试用例

你可以标记无法在某些平台上运行的测试用例或你希望失败的测试用例,以便pytest可以相应地处理它们并提供测试会话的摘要,同时保持测试套件为通过状态

一个Skip意味着你希望如果某些条件得到满足你的测试才执行,否则pytest应该完全跳过运行该用例。常见示例是在非Windows平台上跳过仅限Windows的测试用例,或者跳过依赖于当前不可用的外部资源的测试用例(例如数据库)。

一个xfail意味着已知测试失败并标记原因。一个常见的例子是对尚未实现的功能的测试,或者尚未修复的错误。当测试通过时尽管预计会失败(标记为pytest.mark.xfail),但它在并将在测试摘要及报告中显示为xpass*.

pytest分别计算并列出skipxfail测试。默认情况下不显示有关skip/ xfailed测试的详细信息,以避免输出混乱。你可以使用该-r选项查看与测试进度中显示的“短”字母对应的详细信息:

pytest -rxXs  # show extra info on xfailed, xpassed, and skipped tests

-r可以通过运行找到有关该选项的更多详细信息。pytest -h

(请参阅如何更改命令行选项默认值

跳过测试用例

版本2.9中的新功能。

跳过测试用例的最简单方法是使用skip装饰器标记它,可以传递一个可选的reason

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

或者,也可以通过调用pytest.skip(reason)函数在测试执行或设置期间强制跳过:

def test_function():
    if not valid_config():
        pytest.skip("unsupported configuration")

当在导入时间内无法评估跳过条件时,命令性方法很有用。

也可以在模块级别跳过整个模块 :pytest.skip(reason, allow_module_level=True)

import sys
import pytest

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

参考pytest.mark.skip

skipif

2.0版中的新功能。

如果你希望有条件地跳过某些内容,则可以使用skipif。下面是一个标记在Python3.6之前的解释器上运行时要跳过的测试函数的示例:

import sys

@pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher")
def test_function():
    ...

如果条件True在收集期间评估为,则将跳过测试函数,使用时会在摘要中显示指定的原因-rs

你可以skipif在模块之间共享标记。考虑这个测试模块:

# content of test_mymodule.py
import mymodule

minversion = pytest.mark.skipif(
    mymodule.__versioninfo__ < (1, 1), reason="at least mymodule-1.1 required"
)

@minversion
def test_function():
    ...

你可以导入mark标记并在另一个测试模块中重复使用它:

# test_myothermodule.py
from test_mymodule import minversion

@minversion
def test_anotherfunction():
    ...

对于较大的测试套件,通常最好有一个文件来定义标记,然后在整个测试套件中一致地应用这些标记。

或者,你可以使用条件字符串而不是布尔值,但它们不能在模块之间轻松共享,因此主要出于向后兼容性原因支持它们。

参考pytest.mark.skipif

跳过类或模块的所有测试用例

你可以skipif在类上使用标记(与任何其他标记一样):

@pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")
class TestPosixCalls(object):
    def test_function(self):
        "will not be setup or run under 'win32' platform"

如果条件是True,则此标记将为该类的每个测试方法生成跳过结果。

如果要跳过模块的所有测试用例,可以pytestmark在全局级别使用该名称:

# test_module.py
pytestmark = pytest.mark.skipif(...)

如果将多个skipif装饰器应用于测试用例,则如果任何跳过条件为真,则将跳过该装饰器。

跳过文件或目录

有时你可能需要跳过整个文件或目录,例如,如果测试依赖于Python版本特定的功能或包含你不希望运行pytest的代码。在这种情况下,你必须从集合中排除文件和目录。有关更多信息,请参阅自定义测试集合

跳过缺少的导入依赖关系

你可以在模块级别或测试或测试setup方法中使用以下帮助程序:

docutils = pytest.importorskip("docutils")

如果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")

XFail:将测试函数标记为预期失败

你可以使用xfail标记指示你希望测试失败:

@pytest.mark.xfail
def test_function():
    ...

将运行此测试,但在失败时不会报告回溯。相反,终端报告会将其列在“预期失败”(XFAIL)或“意外传递”(XPASS)部分中。

或者,你也可以XFAIL在测试或设置功能中强制标记测试:

def test_function():
    if not valid_config():
        pytest.xfail("failing configuration (but should work)")

这将无条件地制作test_function XFAIL。请注意,pytest.xfail调用后不会执行其他代码,与标记不同。那是因为它是通过引发已知异常在内部实​​现的。

参考pytest.mark.xfail

strict参数

版本2.9中的新功能。

双方XFAILXPASS除非不失败的测试套件,strict只有关键字的参数作为传递True

@pytest.mark.xfail(strict=True)
def test_function():
    ...

这将导致XPASS(“意外通过”)此测试的结果导致测试套件失败。

你可以strict使用xfail_strictini选项更改参数 的默认值:

[pytest]
xfail_strict=true

reason参数

skipif一样,你也可以在特定平台上标记你对失败的期望:

= (3, 6), reason="python3.6 api changes")
def test_function():
    ...

raises参数

如果你想更具体地说明测试失败的原因,可以在raises参数中指定单个异常或异常元组。

@pytest.mark.xfail(raises=RuntimeError)
def test_function():
    ...

然后,如果测试失败并且没有提到的例外,那么测试将被报告为常规失败raises

run参数

如果测试应标记为xfail并且如此报告但不应该执行,请使用以下run参数False

@pytest.mark.xfail(run=False)
def test_function():
    ...

这对于崩溃解释器的xfailing测试特别有用,应该稍后进行调查。

忽略xfail

通过在命令行上指定:

pytest --runxfail

你可以强制运行并报告xfail标记的测试,就像它根本没有标记一样。这也导致pytest.xfail没有效果。

示例

这是一个简单的测试文件,有几个用法:

import pytest

xfail = pytest.mark.xfail

@xfail
def test_hello():
    assert 0

@xfail(run=False)
def test_hello2():
    assert 0

@xfail("hasattr(os, 'sep')")
def test_hello3():
    assert 0

@xfail(reason="bug 110")
def test_hello4():
    assert 0

@xfail('pytest.__version__[0] != "17"')
def test_hello5():
    assert 0

def test_hello6():
    pytest.xfail("reason")

@xfail(raises=IndexError)
def test_hello7():
    x = []
    x[1] = 1

使用report-on-xfail选项运行它会提供以下输出:

example $ pytest -rx xfail_demo.py
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-4.x.y, py-1.x.y, pluggy-0.x.y
cachedir: $PYTHON_PREFIX/.pytest_cache
rootdir: $REGENDOC_TMPDIR/example
collected 7 items

xfail_demo.py xxxxxxx                                                [100%]
========================= short test summary info ==========================
XFAIL xfail_demo.py::test_hello
XFAIL xfail_demo.py::test_hello2
  reason: [NOTRUN]
XFAIL xfail_demo.py::test_hello3
  condition: hasattr(os, 'sep')
XFAIL xfail_demo.py::test_hello4
  bug 110
XFAIL xfail_demo.py::test_hello5
  condition: pytest.__version__[0] != "17"
XFAIL xfail_demo.py::test_hello6
  reason: reason
XFAIL xfail_demo.py::test_hello7

======================== 7 xfailed in 0.12 seconds =========================

跳过/ xfail与参数多态

使用参数化时,可以将skip和xfail等标记应用于各个测试实例:

import pytest

@pytest.mark.parametrize(
    ("n", "expected"),
    [
        (1, 2),
        pytest.param(1, 0, marks=pytest.mark.xfail),
        pytest.param(1, 3, marks=pytest.mark.xfail(reason="some bug")),
        (2, 3),
        (3, 4),
        (4, 5),
        pytest.param(
            10, 11, marks=pytest.mark.skipif(sys.version_info >= (3, 0), reason="py2k")
        ),
    ],
)
def test_increment(n, expected):
    assert n + 1 == expected```
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容