我是靠谱客的博主 漂亮身影,最近开发中收集的这篇文章主要介绍Pytest权威教程-20编写钩子(hooks)方法函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

编写钩子(hooks)方法函数

钩子(hooks)方法函数验证和执行

pytest为任何给定的钩子(hooks)方法规范调用已注册插件的钩子(hooks)方法函数。让我们看一下钩子(hooks)方法的典型钩子(hooks)方法函数,pytest在收集完所有测试项目后调用。pytest_collection_modifyitems(session,config,items)

当我们pytest_collection_modifyitems在插件中实现一个函数时,pytest将在注册期间验证你是否使用了与规范匹配的参数名称,如果没有则拯救。

让我们看一下可能的实现:

def pytest_collection_modifyitems(config,items):
# called after collection is completed
# you can modify the ``items`` list
...

这里,pytest将传入config(pytest配置对象)和items(收集的测试项列表),但不会传入session参数,因为我们没有在函数签名中列出它。这种动态的“修剪”参数允许pytest“未来兼容”:我们可以引入新的钩子(hooks)方法命名参数而不破坏现有钩子(hooks)方法实现的签名。这是pytest插件的一般长期兼容性的原因之一。

请注意,除了pytest_runtest_*不允许引发异常之外的钩子(hooks)方法函数。这样做会打破pytest运行。

firstresult:首先停止非无结果

大多数对pytest钩子(hooks)方法的调用都会产生一个结果列表,其中包含被调用钩子(hooks)方法函数的所有非None结果。

一些钩子(hooks)方法规范使用该firstresult=True选项,以便钩子(hooks)方法调用仅执行,直到N个注册函数中的第一个返回非None结果,然后将其作为整个钩子(hooks)方法调用的结果。在这种情况下,不会调用其余的钩子(hooks)方法函数。

hookwrapper:在其他钩子(hooks)方法周围执行

版本2.7中的新函数。

pytest插件可以实现钩子(hooks)方法包装器,它包装其他钩子(hooks)方法实现的执行。钩子(hooks)方法包装器是一个生成器函数,它只产生一次。当pytest调用钩子(hooks)方法时,它首先执行钩子(hooks)方法包装器并传递与常规钩子(hooks)方法相同的参数。

在钩子(hooks)方法包装器的屈服点,pytest将执行下一个钩子(hooks)方法实现,并以Result封装结果或异常信息的实例的形式将其结果返回到屈服点。因此,屈服点本身通常不会引发异常(除非存在错误)。

以下是钩子(hooks)方法包装器的示例定义:

import pytest
@pytest.hookimpl(hookwrapper=True)
def pytest_pyfunc_call(pyfuncitem):
do_something_before_next_hook_executes()
outcome = yield
# outcome.excinfo may be None or a (cls,val,tb) tuple
res = outcome.get_result()
# will raise if outcome was exception
post_process_result(res)
outcome.force_result(new_res)
# to override the return value to the plugin system

请注意,钩子(hooks)方法包装器本身不返回结果,它们只是围绕实际的钩子(hooks)方法实现执行跟踪或其他副作用。如果底层钩子(hooks)方法的结果是一个可变对象,它们可能会修改该结果,但最好避免它。

有关更多信息,请参阅插件文档。

钩子(hooks)方法函数排序/调用示例

对于任何给定的钩子(hooks)方法规范,可能存在多个实现,因此我们通常将hook执行视为1:N函数调用,其中N是已注册函数的数量。有一些方法可以影响钩子(hooks)方法实现是在其他人之前还是之后,即在N-sized函数列表中的位置:

# Plugin 1
@pytest.hookimpl(tryfirst=True)
def pytest_collection_modifyitems(items):
# will execute as early as possible
...
# Plugin 2
@pytest.hookimpl(trylast=True)
def pytest_collection_modifyitems(items):
# will execute as late as possible
...
# Plugin 3
@pytest.hookimpl(hookwrapper=True)
def pytest_collection_modifyitems(items):
# will execute even before the tryfirst one above!
outcome = yield
# will execute after all non-hookwrappers executed

这是执行的顺序:

  1. Plugin3的pytest_collection_modifyitems被调用直到屈服点,因为它是一个钩子(hooks)方法包装器。
  2. 调用Plugin1的pytest_collection_modifyitems是因为它标有tryfirst=True
  3. 调用Plugin2的pytest_collection_modifyitems因为它被标记`trylast=True(但即使没有这个标记,它也会在Plugin1之后出现)。
  4. 插件3的pytest_collection_modifyitems然后在屈服点之后执行代码。yield接收一个Result实例,该实例封装了调用非包装器的结果。包装不得修改结果。

这是可能的使用tryfirst,并trylast结合还hookwrapper=True处于这种情况下,它会影响彼此之间hookwrappers的排序。

声明新钩子(hooks)方法

插件和conftest.py文件可以声明新钩子(hooks)方法,然后可以由其他插件实现,以便改变行为或与新插件交互:

在插件注册时调用,允许通过调用添加新的挂钩。pluginmanager.add_hookspecs(module_or_class,prefix)
参数: pluginmanager(*_pytest.config.PytestPluginManager*) - pytest插件管理器

注意:
这个钩子(hooks)方法与之不相容hookwrapper=True

钩子(hooks)方法通常被声明为do-nothing函数,它们只包含描述何时调用钩子(hooks)方法以及期望返回值的文档。

有关示例,请参阅[xdist中。

可选择使用第三方插件的钩子(hooks)方法

由于标准的[验证机制,方法可能有点棘手:如果你依赖未安装的插件,验证将失败并且错误消息对你的用户没有多大意义。

一种方法是将钩子(hooks)方法实现推迟到新的插件,而不是直接在插件模块中声明钩子(hooks)方法函数,例如:

# contents of myplugin.py
class DeferPlugin(object):
"""Simple plugin to defer pytest-xdist hook functions."""
def pytest_testnodedown(self,node,error):
"""standard xdist hook function.
"""
def pytest_configure(config):
if config.pluginmanager.hasplugin("xdist"):
config.pluginmanager.register(DeferPlugin())

这具有额外的好处,允许你根据安装的插件有条件地安装挂钩。

转载于:https://www.cnblogs.com/superhin/p/11478007.html

最后

以上就是漂亮身影为你收集整理的Pytest权威教程-20编写钩子(hooks)方法函数的全部内容,希望文章能够帮你解决Pytest权威教程-20编写钩子(hooks)方法函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部