本文系《pytest源码剖析》系列内容
正在连载,欢迎关注
1. 获取 pytets 所有的 hookspect
通过查看 pytest 源码让咱们知道:
pytest 的执行过程,就是一系列 hook 的调用过程
通过了解 pluggy 插件系统让咱们知道:
hookspec 决定了 hook 的调用方式和效果
hookspec 里包括了:
-
hook 名称
-
hook 参数
-
是否快速返回结果
-
是否支持提前调用
通过 Python 脚本来分析pytest的源码 hookspec.py
中内容,
并将得到的 hook spec保存到 pytest_hookspec_list.csv
提示:
从 pytest 7.2.x 开始,pytest_cmdline_preparse 被移除,改用 pytest_load_initialconftests
故共有 52 个 hook
2. 获取 pytest 所有 hook 之间的关系
知道了 hook的spec之外,还需要搞清楚它们之间的关系,比如
-
hook执行顺序的先后关系
-
hook执行过程的调用关系
这个稍微麻烦一些,好在同样可以编写脚本来进行分析
1. 准备脚本
准备一个多目录、多文件、多用例的执行环境
.
|-- a
| |-- test_a1.py
| `-- test_a2.py
`-- b
|-- test_b1.py
`-- test_b2.py
import pytest
def test_c1():
...
def test_c2():
assert 0
@pytest.mark.skip("skip")
def test_c3():
...
# 也可增加更多类型的用例
2. 记录 Hook 执行过程
hook 的记录可以通过多种方式打开
-
pluggy 提供的分析函数
-
pytest 的 DEBUG 选项
本文使用第二种方式,执行下面的命令即可
set PYTEST_DEBUG=1
pytest sanmu 2> pytest_hook_log.txt
这样 hook 的执行过程jiu就保存到了 pytest_hook_log.txt
对于简单的、独立的 hook ,内容过程结构是这样的
# Hook开始执行
# Hook参数
# HookA返回值
如果在 hook A 的执行过程中调用了 hook B,结构是这样的
# Hook A开始执行
# Hook A参数
# Hook B开始执行
# Hook B参数
# Hook B返回值
# Hook A返回值
根据这些记录,咱们就可以分析出 pytest 的执行流程,进一步掌握 pytest 的核心原理,和内部细节
首发在我的公众号,转载请出处