返回: 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. C#实现将字符串转换成代码并执行

    我们在写JavaScript程序的时候,有一个函数很有趣,eval(),这个方法非常有趣,他可以编译他内部的字符串,并将字符串按照JS代码执行,例如eval(‘alert(“message”)’),执 ...

  2. SQL Server中查找包含某个文本的存储过程 SQL 查找存储过程中出现过的文字怎么查询 查询整个数据库中出现的文本 sql 全局搜索

    --将text替换成你要查找的内容SELECT name, *FROM sysobjects o, syscomments sWHERE o.id = s.id AND text LIKE '%tex ...

  3. Java基础篇(上)

    1.简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java 平台的总称.由James Gosling和同事们共同研发,并在1995年正式推出 ...

  4. Java自学-数字与字符串 字符串

    Java中的字符串String 示例 1 : 创建字符串 字符串即字符的组合,在Java中,字符串是一个类,所以我们见到的字符串都是对象 常见创建字符串手段: 每当有一个字面值出现的时候,虚拟机就会创 ...

  5. python基础04day

    一 引子 数据类型 用途 定义方式 是否多项 有/无序 可/不可变 对应状态 数字     否 —— 不可   字符串    “”‘’“““””” 否 有 不可   列表    [] 是 有 可  同 ...

  6. 【案例】如何让阀门制造提高排产效率?APS系统帮你实现

    随着公司业务发展,苏州纽威阀门公司将承接来自各个国家的更多产品业务,越来越多的客户要求对产品进行精确的交期预估和管理.而目前对产线的产能管理仅限于人工静态产能计算. 由于产品繁多,生产流程各异,不同产 ...

  7. nano命令

    1. 禁止自动换行 # nano -w xxx 2. 保存 Ctrl+O 3. 退出 Ctrl+X 4. 撤销 在请求确认文件名时按Ctrl+C来取消 5. 剪切 Ctrl+K 移动多行,只需多按几次 ...

  8. YUV详解

    YUV格式解析2 又确认了一下H264的视频格式——H264支持4:2:0的连续或隔行视频的编码和解码   YUV(亦称YCrCb)是被欧洲电视系统所采用的一种颜色编码方法(属于PAL).YUV主要用 ...

  9. pycharm 里运行 django 工程 You must either define the environment variable DJANGO_SETTINGS_MODULE 错误

    pycharm 里运行 django 工程出现错误(在命令行直接运行ok): django.core.exceptions.ImproperlyConfigured: Requested settin ...

  10. DLL Injection with Delphi(转载)

    原始链接 I had recently spent some time playing around with the simple to use DelphiDetours package from ...