返回: Pytest权威教程

编写钩子(Hooks)函数

钩子函数验证和执行

Pytest会调用任意给定规格并注册了的插件的钩子方法。让我们看一下一个函数的典型钩子函数

pytest_collection_modifyitems(session,config,items),Pytest在收集完所有测试用例后调用该钩子方法。

当我们在自己的插件中实现一个pytest_collection_modifyitems函数时,Pytest将在注册期间验证你是否使用了与规范匹配的参数名称,如果不符合规范,则废弃掉该方法。

让我们看一下实现该插件的方法:

def pytest_collection_modifyitems(config,items):
# 在收集完测试用例后执行
# 你可以修改items用例列表
...

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

请注意,除了pytest_runtest_*这种测试运行期间的钩子方法,其他钩子方法不允许抛出异常,不然会破坏Pytest的运行流程。

firstresult: 遇到第一个有效(非None)结果返回

通常Pytest钩子函数的调用,都会产生一个包含所有所调用钩子方法的有效结果组成的列表。

一些钩子函数规格使用firstresult=True选项,以便钩子函数调用,直到多个个注册钩子函数中的第一个返回有效结果,然后将其作为整个钩子函数调用的结果。这种情况下,其余的钩子函数不会再调用。

hookwrapper:在其他钩子函数周围执行

版本2.7中的新函数。

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

在钩子函数装饰器的yield处,Pytest将执行下一个钩子函数实现,并以Result对象的形式,封装结果或异常信息的实例的形式将其结果返回到yield处。因此,yield处通常本身不会抛出异常(除非存在错误)。

以下是钩子函数装饰器的示例:

import pytest

@pytest.hookimpl(hookwrapper=True)
def pytest_pyfunc_call(pyfuncitem):
do_something_before_next_hook_executes()
outcome = yield
# outcome的退出信息(outcome.excinfo)可能是None或者(cls,val,tb)组成的元祖
res = outcome.get_result() # 如果outcome出错会抛出异常
post_process_result(res)
outcome.force_result(new_res) # 覆盖插件系统的返回值

请注意,钩子函数装饰器本身不返回结果,它们只是围绕实际的钩子函数实现执行跟踪或其他额外作用。如果底层钩子函数的结果是一个可变对象,这可能会修改该结果,因此最好避免对动态结果这样使用。

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

钩子(Hooks)函数排序/调用示例

对于任何给定的钩子函数规格,可能存在多个实现,因此我们通常将钩子函数执行视为1:N的函数调用,其中N是已注册函数的数量。有一些方法可以影响钩子函数实现是在其他之前还是之后,即在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被调用直到注入点,因为它是一个钩子函数装饰器。
  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的排序。

声明新的钩子函数

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

在插件注册时调用,允许通过调用添加新的钩子函数。pluginmanager.add_Hookspecs(module_or_class,prefix)

参数: pluginmanager(_pytest.config.PytestPluginManager) - Pytest插件管理器

注意:

这个钩子函数与之不相容hookwrapper=True。

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

有关示例,请参阅:xdist插件。

使用第三方插件的钩子函数

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

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

# 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())

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

Pytest权威教程19-编写钩子(Hooks)方法函数的更多相关文章

  1. Pytest权威教程02-Pytest 使用及调用方法

    目录 Pytest 使用及调用方法 使用python -m pytest调用pytest 可能出现的执行退出code 获取版本路径.命令行选项及环境变量相关帮助 第1(N)次失败后停止测试 指定及选择 ...

  2. Pytest权威教程18-插件编写

    [TOC] 返回: Pytest权威教程 插件编写 很容易为你自己的项目实现[本地conftest插件或可以在许多项目中使用的可[安装的插件,包括第三方项目.如果你只想使用但不能编写插件,请参阅[安装 ...

  3. Pytest权威教程(官方教程翻译)

    Pytest权威教程01-安装及入门 Pytest权威教程02-Pytest 使用及调用方法 Pytest权威教程03-原有TestSuite的执行方法 Pytest权威教程04-断言的编写和报告 P ...

  4. Pytest权威教程03-原有TestSuite的执行方法

    目录 原有TestSuite的执行方法 使用pytest运行已存在的测试套件(test suite) 返回: Pytest权威教程 原有TestSuite的执行方法 Pytest可以与大多数现有的测试 ...

  5. Pytest权威教程21-API参考-04-钩子(Hooks)

    目录 钩子(Hooks) 引导时的Hook方法 初始化时的Hook方法 测试运行时的Hook方法 收集用例时的Hook方法 生成测试结果时的Hook方法 调试/交互Hook方法 返回: Pytest权 ...

  6. Pytest权威教程04-断言的编写和报告

    目录 断言的编写和报告 使用assert语句进行断言 异常断言 警示断言 使用上下文对比 自定义断言对比信息 高级断言内省 返回: Pytest权威教程 断言的编写和报告 使用assert语句进行断言 ...

  7. Pytest权威教程13-Fixture方法及测试用例的参数化

    目录 Fixture方法及测试用例的参数化 @pytest.mark.parametrize:参数化测试函数 基本的pytest_generate_tests例子 更多示例 返回: Pytest权威教 ...

  8. Pytest权威教程21-API参考-05-对象(Objects)

    目录 对象(Objects) CallInfo Class Collector Config ExceptionInfo FixtureDef FSCollector Function Item Ma ...

  9. Pytest权威教程21-API参考-03-夹具(Fixtures)

    目录 夹具(Fixtures) @ pytest.fixture config.cache的 capsys capsysbinary capfd capfdbinary doctest_namespa ...

随机推荐

  1. 2019 第一视频java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.第一视频等公司offer,岗位是Java后端开发,因为发展原因最终选择去了第一视频,入职一年时间了,也成为了面 ...

  2. Spring MVC异常友好展示

    官网 https://docs.spring.io/spring/docs/4.3.25.RELEASE/spring-framework-reference/htmlsingle/ Springmv ...

  3. Java 之 线程的生命周期(线程状态)

    一.线程的生命周期 (1)新建状态 new 好了一个线程对象,此时和普通的 Java对象并没有区别. (2)就绪 就绪状态的线程是具备被CPU调用的能力和状态,也只有这个状态的线程才能被CPU调用.即 ...

  4. Hibernate 5.x 生成 SessionFactory 源码跟踪分析

    我们要使用 Hibernate 的功能,首先需要读取 Hibernate 的配置文件,根据配置启动 Hibernate ,然后创建 SessionFactory. 创建 SessionFactory ...

  5. 【Nginx】使用certbot安装免费https证书使Nginx支持Https请求

    certbot官网:https://certbot.eff.org/lets-encrypt/centosrhel7-nginx 一.安装步骤 1)安装certbot,执行  sudo yum ins ...

  6. 【异常】ERROR in ch.qos.logback.core.joran.spi.Interpreter@159:22 - no applicable action for [charset], current ElementPath is [[configuration][appender][encoder][charset]]

    一.异常信息 Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at ...

  7. 折腾deepin修改终端语言

    原创作品,作者是博客园sogeisetsu,转载请注明来源sogeisetsu.cnblogs.com 唉-都怪当初没学扎实,改个终端语言花费了半天. 首先,介绍一下我的情况 有两个用户,一个是roo ...

  8. Broadcast,Scatter,Gather,Reduce,All-reduce分别是什么?

    Broadcast 看名字就很好理解了,其实就是把同一份数据分发广播给所有人,示意图如下: Scatter 不同于Broadcast, scatter可以将不同数据分发给不同的进程. Gather 这 ...

  9. 图像处理中Stride和Width的关系

    一行有 11 个像素(Width = 11), 对一个 32 位(每个像素 4 字节)的图像, Stride = 11 * 4 = 44. 但还有个字节对齐的问题, 譬如: 一行有 11 个像素(Wi ...

  10. P5021 赛道修建[贪心+二分]

    题目描述 C 城将要举办一系列的赛车比赛.在比赛前,需要在城内修建 mm 条赛道. C 城一共有 nn 个路口,这些路口编号为 1,2,-,n1,2,-,n,有 n-1n−1 条适合于修建赛道的双向通 ...