Pytest权威教程19-编写钩子(Hooks)方法函数
编写钩子(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
这是执行的顺序:
- Plugin3的pytest_collection_modifyitems被调用直到注入点,因为它是一个钩子函数装饰器。
- 调用Plugin1的pytest_collection_modifyitems是因为它标有
tryfirst=True
。 - 调用Plugin2的pytest_collection_modifyitems因为它被标记`trylast=True(但即使没有这个标记,它也会在Plugin1之后出现)。
- 插件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)方法函数的更多相关文章
- Pytest权威教程02-Pytest 使用及调用方法
目录 Pytest 使用及调用方法 使用python -m pytest调用pytest 可能出现的执行退出code 获取版本路径.命令行选项及环境变量相关帮助 第1(N)次失败后停止测试 指定及选择 ...
- Pytest权威教程18-插件编写
[TOC] 返回: Pytest权威教程 插件编写 很容易为你自己的项目实现[本地conftest插件或可以在许多项目中使用的可[安装的插件,包括第三方项目.如果你只想使用但不能编写插件,请参阅[安装 ...
- Pytest权威教程(官方教程翻译)
Pytest权威教程01-安装及入门 Pytest权威教程02-Pytest 使用及调用方法 Pytest权威教程03-原有TestSuite的执行方法 Pytest权威教程04-断言的编写和报告 P ...
- Pytest权威教程03-原有TestSuite的执行方法
目录 原有TestSuite的执行方法 使用pytest运行已存在的测试套件(test suite) 返回: Pytest权威教程 原有TestSuite的执行方法 Pytest可以与大多数现有的测试 ...
- Pytest权威教程21-API参考-04-钩子(Hooks)
目录 钩子(Hooks) 引导时的Hook方法 初始化时的Hook方法 测试运行时的Hook方法 收集用例时的Hook方法 生成测试结果时的Hook方法 调试/交互Hook方法 返回: Pytest权 ...
- Pytest权威教程04-断言的编写和报告
目录 断言的编写和报告 使用assert语句进行断言 异常断言 警示断言 使用上下文对比 自定义断言对比信息 高级断言内省 返回: Pytest权威教程 断言的编写和报告 使用assert语句进行断言 ...
- Pytest权威教程13-Fixture方法及测试用例的参数化
目录 Fixture方法及测试用例的参数化 @pytest.mark.parametrize:参数化测试函数 基本的pytest_generate_tests例子 更多示例 返回: Pytest权威教 ...
- Pytest权威教程21-API参考-05-对象(Objects)
目录 对象(Objects) CallInfo Class Collector Config ExceptionInfo FixtureDef FSCollector Function Item Ma ...
- Pytest权威教程21-API参考-03-夹具(Fixtures)
目录 夹具(Fixtures) @ pytest.fixture config.cache的 capsys capsysbinary capfd capfdbinary doctest_namespa ...
随机推荐
- Pika 连接 rabbitmq 集群
原文:https://blog.csdn.net/Tech_Salon/article/details/82890431 使用 Pika 连接 rabbitmq 集群使用 python 编程经常会用到 ...
- [Linux] 树莓派编译python3.7.4
python3.7.4 源码编译后遇到ssl错误: pip is configured with locations that require TLS/SSL, however the ssl mod ...
- Computer Networking: A Top Down Approach
目录 Chapter 1: Computer Networks and the Internet 1. What is the Internet? 2. The Network Edge 3. The ...
- QT制作一个位图画图板程序
本文学习如何创建一个Qt绘制程序,用户将能够通过使用不同的尺寸和画笔的颜色来表达他们的创造力. 主要功能:保存画板内容为图片.清除画板内容.设置画板大小.设置画笔颜色 新建基于QMainWindow的 ...
- Cheat Engine 指针
打开游戏 扫描时间的流程就不多说了 扫描结果 寻找基地址 右击扫描到的地址,选择什么改写了这个地址 会弹出如下窗口 不用管这个窗口,去改变一下游戏时间,出现如下图 随便打开一个,找到了数据块地址和偏移 ...
- Java实现简易聊天室
Java实现简易聊天室 在学习<Java从入门到精通>这本书,网络通信,基于TCP实现的简易聊天室,我这里对书中的代码略做了修改,做个记录. 这里先放一下运行效果图,代码放在最后. 运行效 ...
- 下载文件时-修改文件名字 Redis在Windows中安装方法 SVN安装和使用(简单版) WinForm-SQL查询避免UI卡死 Asp.Net MVC Https设置
下载文件时-修改文件名字 1后台代码 /// <summary> /// 文件下载2 /// </summary> /// <param name="Fil ...
- 【Git版本控制】Git初始化一个仓库
git init //初始化一个本地库 git add -A//将所有的文件添加到暂存区 git commit -m “首次提交” //将暂存区的文件提交到版本库 git remote add ori ...
- python 导入导出依赖包命令
程序中必须包含一个 requirements.txt 文件,用于记录所有依赖包及其精确的版本号.如果 要在另一台电脑上重新生成虚拟环境,这个文件的重要性就体现出来了,例如部署程序时 使用的电脑.pip ...
- MySQL 8.0 的xtrabackup备份
xtrabackup 备份语句: fname=`date +%F_%H-%M-%S` mkdir -p /mnt/dbbak/db_$fname xtrabackup --defaults-file= ...