钩子 【pytest官方文档】解读-插件开发之hooks 函数

上一节讲到如何安装和使用第三方插件 , 用法很简单 。接下来解读下如何自己开发pytest插件 。
但是 , 由于一个插件包含一个或多个钩子函数开发而来 , 所以在具体开发插件之前还需要先学习hooks函数 。
一、什么是 hooks 函数简单来说 , 在 pytest 的代码中 , 预留出了一些函数供我们修改 , 以便来改变pytest工作方式 , 这些函数就是hooks函数 , 我们可以直接重写函数里的内容 。
比如 , 在 pytest代码路径\Lib\site-packages\_pytest\hookspec.py中 , 可以看到 pytest 定义好的 hook 规范 , 方便我们在开发插件的时候参考规范来调用对应的hooks函数 。

钩子 【pytest官方文档】解读-插件开发之hooks 函数

文章插图
二、hooks 函数的分类【钩子 【pytest官方文档】解读-插件开发之hooks 函数】hooks函数的职责分类来看 , 大概如下几类:
  • Bootstrapping hooks:引导类钩子 , 用来调用已经早就注册好的内部插件和第三方插件 。
  • Collection hooks:集合类钩子 , pytest 调用集合钩子来收集文件和目录 。
  • Test running (runtest) hooks:测试运行相关的钩子 , 所有与测试运行相关的钩子都接收一个pytest.Item对象 。
  • Reporting hooks:与Session 会话相关的钩子 。
  • Debugging/Interaction hooks:调试/交互钩子 , 少有的可以用于特殊的报告或与异常交互的钩子函数 。
可供调用的钩子函数有很多 , 功能也是各式各样的 , 有兴趣的童鞋可以进一步细看官方文档里的介绍 。我们就是要通过不同钩子函数具备的功能 , 来实现我们自定义的需求 。
三、编写 hooks 函数开发本地插件写一个插件示例 。
比如我们平时执行case的时候 , 一通跑完可能会出现不少失败的case , 那通常我可能就会翻控制台的输出来找出哪些case失败了 。
但是控制台里输出的信息有很多 , 于是乎我想直接把测试失败的case信息存到一个本地文件里 , 我直接打开就可以看到所有失败的case 。
先写一个case文件里的建议测试用例:
# content of mytest/tests.pydef test_failed():assert Falsedef test_passed():assert Truedef test_failed2():assert False然后再同级目录下创建一个conftest文件 , 之前聊fixture时候就说过 , conftest里的内容就是本地插件了 。
先直接放上插件代码:
# content of mytest/conftest.pyimport pytestfrom pathlib import Pathfrom _pytest.main import Sessionfrom _pytest.nodes import Itemfrom _pytest.runner import CallInfofrom _pytest.terminal import TerminalReporterFAILURES_FILE = Path() / "failures.txt"@pytest.hookimpl()def pytest_sessionstart(session: Session):print("Hello 把苹果咬哭")if FAILURES_FILE.exists():FAILURES_FILE.unlink()FAILURES_FILE.touch()@pytest.hookimpl(hookwrapper=True)def pytest_runtest_makereport(item: Item, call: CallInfo):outcome = yieldresult = outcome.get_result()if result.when == "call" and result.failed:try:with open(str(FAILURES_FILE), "a") as f:f.write(result.nodeid + "\n")except Exception as e:print("ERROR", e)pass解析
1. 重写钩子函数首先 , 关于pathlib模块就是用来做一些路径操作的库 , 因为我要在本地路径中进行文件相关操作 。
def pytest_sessionstart()中做的事情就是先看下本地是否存在这个名字叫failures.txt的文件 , 有的话就删除 , 没有就新建 。

经验总结扩展阅读