返回: 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. dapper.common新增概念object to sql

    Dapper.Common About author Email:@qq.com QQ: QQGroup: Config DbContextFactory.AddDataSource(new Data ...

  2. vue组件5 组件和v-for指令

    使用v-for遍历一个数组的时候,并且给定的数组变化时vue不会重复生成所有的元素,而是智能的找到需要更改的元素,并只改变这些元素 key属性可以告诉vue数组中的每个元素都应该与页面上的哪个元素相关 ...

  3. vue 实现滚动到页面底部开始加载更多

    直接上代码: <template> <div class="newsList"> <div v-for="(items, index) in ...

  4. 英语bitellos钻石bitellos单词

    大颗粒的钻石叫做bitellos,四大钻石指的就是“摄政王”.“南非之星”.“蓝色希望”和“光明之山”四颗钻石.经过琢磨的钻石光彩夺目.灿烂无比,历来被誉为“宝石之王”,科研领域里大颗粒的钻石叫做bi ...

  5. android studio学习----调试---断点调试

    Android Studio调试其实也非常方便,一般问题直接通过AS的DDMS的Logcat就可以搞定.AS支持类似Eclipse的DDMS的所有功能.这里要说的是疑难问题的调试方式,即断点调试. 首 ...

  6. java接口中的成员方法和成员变量

    接口的含义理解:接口可以理解成统一的"协议",而接口中的属性也属于协议中的内容;但是接口的属性都是公共的,静态的,最终的 接口的成员特点:A:成员变量 只能是常量.默认修饰符 pu ...

  7. Java 使用properties配置文件加载配置

    一般我们不把数据库的配置信息写死在代码中. 写好代码后,编译.调试,成功后只把输出目录中的东西(jar包..class文件.资源文件等)拷贝到服务器上,由运维来管理.服务器上是没有源文件的(.java ...

  8. mongodb 通过嵌入文档中的字段排序

    mongodb中的全部数据: db.testInfo.find({}) .sort({_id:-1}) .limit(100) 查询结果: /* 1 createdAt:2019/10/11 下午5: ...

  9. Pycharm安装模块提示module 'pip' has no attribute 'main'的问题

    解决pycharm问题:module 'pip' has no attribute 'main' 转自: <解决pycharm问题:module 'pip' has no attribute ' ...

  10. 手写神经网络Python深度学习

    import numpy import scipy.special import matplotlib.pyplot as plt import scipy.misc import glob impo ...