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


3. hook函数中的 hookwrapper回到插件代码本身 , 也用到了一个参数hookwrapper=True

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

文章插图
默认情况下,我们之间重写hook函数来彻底改变它要做的事情 , 就像插件代码里第一个hook函数pytest_sessionstart一样 。
hookwrapper=True时,等于是我们实现了一个hook函数的包装器 。钩子包装器是一个生成器函数,它只产生一次 。
当 pytest 调用钩子时 , 首先执行钩子包装器,并像常规钩子一样传递相同的参数 。
yield关键字大家都熟悉了 , 当代码执行到这里的时候会暂停一下,继续执行下一个钩子,并且会把所有的结果或者异常封装成一个result对象返回到yield这里 。
钩子包装器本身并不返回结果,只是在实际的钩子实现的外面做一些其他的事情 。
我们的插件功能其实也并不是要修改这个钩子本身测试报告的内容,所以就直接通过hookwrapper=True将我们的pytest_runtest_makereport写成一个包装好的钩子 。
接下来就是具体功能的代码,判断当用例测试结果是fail,就写到本地文件中 。
运行运行一下测试用例,看下我们插件的执行情况 。
钩子 【pytest官方文档】解读-插件开发之hooks 函数

文章插图
查看下failures.txt内容,结果正确 。
钩子 【pytest官方文档】解读-插件开发之hooks 函数

文章插图
四、钩子函数排序/调用示例存在这样的情况,对于同一个钩子规范,可能会存在多个实现 。这种情况下可以使用参数tryfirsttrylast来影响钩子的调用顺序 。
# Plugin 1@pytest.hookimpl(tryfirst=True)def pytest_collection_modifyitems(items):# 尽可能早的执行...# Plugin 2@pytest.hookimpl(trylast=True)def pytest_collection_modifyitems(items):# 尽可能晚的执行...# Plugin 3@pytest.hookimpl(hookwrapper=True)def pytest_collection_modifyitems(items):# 会在上面的 tryfirst 之前执行outcome = yield# 在执行所有非钩子包装器之后执行具体执行顺序如下:
  1. Plugin3pytest_collection_modifyitems一直调用到yield,因为它是一个钩子包装器 。
  2. Plugin1pytest_collection_modifyitems被调用 , 因为它被标记为tryfirst=True
  3. Plugin2pytest_collection_modifyitems被调用,因为它被标记为trylast=True(但即使没有这个标记,它也会在Plugin1之后) 。
  4. Plugin3pytest_collection_modifyitems继续在yield执行代码,yield接收一个Result实例 。
关于hook本篇先到此 , 剩下的内容另起篇幅了 。
最后,闻道有先后,文章有遗漏,欢迎交流 。
【钩子 【pytest官方文档】解读-插件开发之hooks 函数】

推荐阅读