Pytest官方教程-22-API参考-Fuctions

目录:

  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自动补全设置

API参考-Fuctions

22-API参考-01-Functions

参考
该页面包含对pytest API的完整参考。

方法(Functions)

pytest.approx

断言两个数字(或两组数字)在某个容差范围内彼此相等。

由于浮点运算复杂性,我们直觉期望相等的数字并不总是如此:

 0.1 + 0.2 == 0.3
False

编写测试时通常会遇到此问题,例如,确保浮点值是您期望的值。处理此问题的一种方法是断言两个浮点数等于某个适当的容差范围内:

 abs((0.1 + 0.2) - 0.3) < 1e-6
True

但是,这样的比较写作起来既乏味又难以理解。此外,通常不鼓励像上面这样的绝对比较,因为没有适合所有情况的容忍度。 1e-6对周围的数字有好处1,但对于非常大的数字而言太小而对于非常小的数字而言太大。最好将公差表示为预期值的一小部分,但这样的相对比较更难以正确和简洁地书写。

approx班采用语法是尽可能直观执行浮点比较:

 from pytest import approx
>>> 0.1 + 0.2 == approx(0.3)
True

相同的语法也适用于数字序列:

 (0.1 + 0.2, 0.2 + 0.4) == approx((0.3, 0.6))
True

字典

 {'a': 0.1 + 0.2, 'b': 0.2 + 0.4} == approx({'a': 0.3, 'b': 0.6})
True

numpy 数组:

 import numpy as np                                                          
>>> np.array([0.1, 0.2]) + np.array([0.2, 0.4]) == approx(np.array([0.3, 0.6])) 
True

对于numpy标量的数组:

 import numpy as np                                         
>>> np.array([0.1, 0.2]) + np.array([0.2, 0.1]) == approx(0.3) 
True

默认情况下,approx1e-6其预期值的相对容差 (即百万分之一)内的数字视为相等。如果预期值是这样的0.0,那么这种处理会产生令人惊讶的结果 ,因为除了0.0本身之外什么都不是0.0。为了不那么令人惊讶地处理这种情况,approx还要考虑在1e-12其预期值的绝对容差内的数字是相等的。Infinity和NaN是特殊情况。无论相对容差如何,无穷大只被视为与自身相等。默认情况下,NaN不被视为等于任何内容,但您可以通过将nan_ok参数设置为True 来使其等于自身。(这是为了便于比较使用NaN的数组表示“无数据”。)

通过将参数传递给approx构造函数,可以更改相对容差和绝对容差:

 1.0001 == approx(1)
False
>>> 1.0001 == approx(1, rel=1e-3)
True
>>> 1.0001 == approx(1, abs=1e-3)
True

如果您指定abs但不指定rel,则比较将不会考虑相对容差。换句话说,1e-6如果超过指定的绝对容差,则默认相对容差范围内的两个数字仍将被视为不相等。如果同时指定两个 absrel,如果满足任一公差,则数字将被视为相等:

 1 + 1e-8 == approx(1)
True
>>> 1 + 1e-8 == approx(1, abs=1e-12)
False
>>> 1 + 1e-8 == approx(1, rel=1e-6, abs=1e-12)
True

如果您正在考虑使用approx,那么您可能想知道它与比较浮点数的其他好方法的比较。所有这些算法都基于相对和绝对容差,并且应该在大多数情况下达成一致,但它们确实存在有意义的差异:

  • math.isclose(a, b, rel_tol=1e-9, abs_tol=0.0):True如果相对误差满足WRT无论是ab,或者如果绝对容差得到满足。因为相对容差是a和两者一起计算的b,所以该测试是对称的(即既不是a也不 b是“参考值”)。如果要进行比较,则必须指定绝对容差,0.0因为默认情况下没有容差。仅在python> = 3.5中可用。 更多信息…
  • numpy.isclose(a, b, rtol=1e-5, atol=1e-8):如果和之间的差值小于相对容差wrt 和绝对容差之a和,b则为真b。由于相对容差仅计算为wrt b,因此该测试是不对称的,您可以将其b视为参考值。支持比较序列由numpy.allclose。提供。 更多信息…
  • unittest.TestCase.assertAlmostEqual(a, b):如果a并且b 在绝对容差范围内,则为真1e-7。不考虑相对容差,并且不能改变绝对容差,因此该功能不适用于非常大或非常小的数字。此外,它只在子类中可用,unittest.TestCase并且它很难看,因为它不遵循PEP8。 更多信息…
  • a == pytest.approx(b, rel=1e-6, abs=1e-12):如果满足相对容差b或者满足绝对容差,则为真。由于相对容差仅计算为wrt b,因此该测试是不对称的,您可以将其b视为参考值。在明确指定绝对公差而非相对公差的特殊情况下,仅考虑绝对公差。

警告

在3.2版中更改。

为了避免不一致的行为,TypeError是提高了>>=<<=比较。以下示例说明了问题:

 0.1 + 1e-10  # calls approx(0.1).__gt__(0.1 + 1e-10)
assert 0.1 + 1e-10 > approx(0.1)  # calls approx(0.1).__lt__(0.1 + 1e-10)

在第二个例子中,人们期望 被调用。但相反,用于比较。这是因为丰富比较的调用层次结构遵循固定行为。更多信息…approx(0.1).__le__(0.1 + 1e-10)``approx(0.1).__lt__(0.1 +1e-10)

pytest.fail

教程Skip和xfail:处理无法成功的测试
使用给定消息显式失败执行测试。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: |

  • msgstr) - 显示用户失败原因的消息。
  • pytracebool) - 如果为false,则msg表示完整的失败信息,并且不报告任何python回溯。

pytest.skip

使用给定消息跳过执行测试。

应仅在测试(设置,调用或拆除)期间或使用allow_module_level标志在收集期间调用此函数。此函数也可以在doctests中调用。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: | allow_module_levelbool) - 允许在模块级别调用此函数,跳过模块的其余部分。默认为False。 |

注意:
最好在可能的情况下使用pytest.mark.skipif标记来声明在某些条件下跳过的测试,例如不匹配的平台或依赖项。同样,使用指令(请参阅doctest.SKIP)静态跳过doctest。# doctest:+SKIP

pytest.importorskip

导入并返回请求的模块modname,或者如果无法导入模块,则跳过当前测试。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: |

  • modnamestr) - 要导入的模块的名称
  • minversionstr) - 如果给定,导入的模块__version__属性必须至少为此最小版本,否则仍会跳过测试。
  • reasonstr) - 如果给定,则无法导入模块时,此原因显示为消息。

pytest.xfail

由于给定的原因,强制执行测试或设置功能。

只应在测试(设置,调用或拆卸)期间调用此函数。

注意

最好在可能的情况下使用pytest.mark.xfail标记,在某些条件(如已知错误或缺少的功能)下声明测试是否为xfailed。

pytest.exit

退出测试过程。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: |

  • msgstr) - 退出时显示的消息。
  • returncodeint) - 返回退出pytest时使用的代码。

pytest.main

执行进程内测试运行后返回退出代码。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: |

  • args - 命令行参数列表。
  • plugins - 初始化期间要自动注册的插件对象列表。

pytest.param

pytest.mark.parametrize调用或 参数化夹具中指定参数。

@pytest.mark.parametrize("test_input,expected", [
    ("3+5", 8),
    pytest.param("6*9", 42, marks=pytest.mark.xfail),
])
def test_eval(test_input, expected):
    assert eval(test_input) == expected

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: |

  • values - 按顺序的参数集值的变量args。
  • 标记 - 要应用于此参数集的单个标记或标记列表。
  • idstr) - 属于此参数集的id。

pytest.raises

教程关于预期异常的断言

断言代码块/函数调用会引发expected_exception 或引发失败异常。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 参数: |

  • match - 如果指定,则断言异常与text或regex匹配
  • 消息 - (自4.1弃用)如果指定,提供了一种定制的失败消息,如果异常没有升高

|

使用pytest.raises的上下文管理器,这将捕获特定类型的异常:

 with raises(ZeroDivisionError):
...    1/0

如果代码块没有引发预期的异常(ZeroDivisionError在上面的示例中),或者根本没有异常,则检查将失败。

您还可以使用keyword参数match来断言异常与text或regex匹配:

 with raises(ValueError, match='must be 0 or None'):
...     raise ValueError("value must be 0 or None")

>>> with raises(ValueError, match=r'must be \d+/pre>):
...     raise ValueError("value must be 42")

上下文管理器生成一个ExceptionInfo对象,可用于检查捕获的异常的详细信息:

 with raises(ValueError) as exc_info:
...     raise ValueError("value must be 42")
>>> assert exc_info.type is ValueError
>>> assert exc_info.value.args[0] == "value must be 42"

自4.1版本后不推荐使用:在上下文管理器表单中,您可以使用keyword参数 message指定在pytest.raises检查失败时将显示的自定义失败消息。这已被弃用,因为它被认为是容易出错的,因为用户通常意味着使用它match

注意

pytest.raises用作上下文管理器时,值得注意的是,应用正常的上下文管理器规则,并且引发的异常必须是上下文管理器范围内的最后一行。之后,在上下文管理器范围内的代码行将不会被执行。例如:

 value = 15
>>> with raises(ValueError) as exc_info:
...     if value > 10:
...         raise ValueError("value must be <= 10")
...     assert exc_info.type is ValueError  # this will not execute

相反,必须采取以下方法(注意范围的差异):

 with raises(ValueError) as exc_info:
...     if value > 10:
...         raise ValueError("value must be <= 10")
...
>>> assert exc_info.type is ValueError

使用 pytest.mark.parametrize

使用pytest.mark.parametrize时 ,可以对测试进行参数化,使得某些运行引发异常,而其他运行则不会。

有关示例,请参阅参数化条件提升

遗产形式

可以通过传递一个名为lambda来指定一个可调用的:

 raises(ZeroDivisionError, lambda: 1/0)
<ExceptionInfo ...>

或者你可以用参数指定一个任意的callable:

 def f(x): return 1/x
...
>>> raises(ZeroDivisionError, f, 0)
<ExceptionInfo ...>
>>> raises(ZeroDivisionError, f, x=0)
<ExceptionInfo ...>

上面的表单完全受支持,但不建议使用新代码,因为上下文管理器表单被认为更具可读性且不易出错。

注意:
与Python中捕获的异常对象类似,显式清除对返回ExceptionInfo对象的本地引用可以帮助Python解释器加速其垃圾回收。

清除这些引用会中断引用循环(ExceptionInfo- >捕获异常 - >帧堆栈引发异常 - >当前帧堆栈 - >局部变量 - > ExceptionInfo),这会使Python保留从该循环引用的所有对象(包括当前帧中的所有局部变量) )活着,直到下一个循环垃圾收集运行。有关try更多详细信息,请参阅官方Python 语句文档。

pytest.deprecated_call

教程确保代码触发弃用警告

上下文管理器,可用于确保代码块触发a DeprecationWarningPendingDeprecationWarning

 import warnings
>>> def api_call_v2():
...     warnings.warn('use v3 of this api', DeprecationWarning)
...     return 200

>>> with deprecated_call():
...    assert api_call_v2() == 200

deprecated_call也可以通过传递函数来使用,*args并且*kwargs在这种情况下,它将确保调用产生上面的警告类型之一。func(*args, **kwargs)

pytest.register_assert_rewrite

教程断言重写

注册一个或多个要在导入时重写的模块名称。

此函数将确保此模块或程序包内的所有模块将重写其assert语句。因此,您应确保在实际导入模块之前调用此方法,如果您是使用包的插件,则通常在init.py中调用。

<colgroup><col class="field-name" style="hyphens: manual;"><col class="field-body"></colgroup>
| 举: | TypeError - 如果给定的模块名称不是字符串。 |

pytest.warns

教程使用警告功能发出警告

断言代码会引发一类特定的警告。

具体来说,参数expected_warning可以是警告类或警告类序列,并且with块内部必须发出该类或类的警告。

该助手生成一个warnings.WarningMessage对象列表,每个警告引发一个对象。

此函数可用作上下文管理器,pytest.raises也可以使用任何其他方法 :

 with warns(RuntimeWarning):
...    warnings.warn("my warning", RuntimeWarning)

在上下文管理器表单中,您可以使用keyword参数match来断言异常与text或regex匹配:

 with warns(UserWarning, match='must be 0 or None'):
...     warnings.warn("value must be 0 or None", UserWarning)

>>> with warns(UserWarning, match=r'must be \d+/pre>):
...     warnings.warn("value must be 42", UserWarning)

>>> with warns(UserWarning, match=r'must be \d+/pre>):
...     warnings.warn("this is not here", UserWarning)
Traceback (most recent call last):
  ...
Failed: DID NOT WARN. No warnings of type ...UserWarning... was emitted...

pytest.freeze_includes

教程冻结pytest

返回pytest使用的模块名称列表,应由cx_freeze包含。

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

推荐阅读更多精彩内容