为啥用pytest_sessionstart
这个hook函数 , 因为通过查看官方API文档里的介绍 , 发现这个钩子函数是在创建Session对象之后 , 且在执行收集和进入运行测试循环之前调用 , 所以很适合用在这里 。
所以直接重写这个hook函数来实现我们定义的功能 。
2. hook函数中的 firstresult示例中使用hook函数pytest_runtest_makereport
, 同样通过查看官方API介绍 , 它的作用是为测试用例的每个setup
、运行
和tearDown
阶段创建TestReport
。而插件要做的事情 , 就是要在用例执行后获取到状态 , 若是失败就存放到本地txt
文件 。
当查看hook规范
时候 , 发现一个装饰器参数firstresult=True
。

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

文章插图
查看下
failures.txt
内容 , 结果正确 。
文章插图
四、钩子函数排序/调用示例存在这样的情况 , 对于同一个钩子规范 , 可能会存在多个实现 。这种情况下可以使用参数
tryfirst
和trylast
来影响钩子的调用顺序 。# 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# 在执行所有非钩子包装器之后执行
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 五 微软出品自动化神器【Playwright+Java】系列 之常见点击事件操作
- 汤圆冻太久里面有硬块煮不熟
- 凉粉怎么保存
- 黄龙溪属于成都还是眉山
- 今夏蚊子都热死了吗 蚊子也怕热吗
- 空调吹出酸臭味如何解决
- 干豆皮晒干了能放几年
- 有什么药可以把马蜂全部杀死
- 生菜焯水多久
- 降真香是什么