本文系《pytest源码剖析》系列内容
正在连载,欢迎关注
3. 插件机制实例分析
写完软件本体之后,继续编写插件
02 编写插件
以一个名为 eggsample-spam
的项目编写插件,
需要创建一个文件,使用 eggsample.hookimpl
装饰 hook 实现即可
# eggsample-spam/eggsample_spam.py
import eggsample
@eggsample.hookimpl
def eggsample_add_ingredients(ingredients):
"""Here the caller expects us to return a list."""
if "egg" in ingredients:
spam = ["lovely spam", "wonderous spam"]
else:
spam = ["splendiferous spam", "magnificent spam"]
return spam
@eggsample.hookimpl
def eggsample_prep_condiments(condiments):
"""Here the caller passes a mutable object, so we mess with it directly."""
try:
del condiments["steak sauce"]
except KeyError:
pass
condiments["spam sauce"] = 42
return "Now this is what I call a condiments tray!"
当然,为了插件能够进行安装,也需要额外创建一个 setup.py
# eggsample-spam/setup.py
from setuptools import setup
setup(
name="eggsample-spam",
install_requires="eggsample",
entry_points={"eggsample": ["spam = eggsample_spam"]},
py_modules=["eggsample_spam"],
)
在插件中,实现了两个 hook:
-
eggsample_add_ingredients
-
eggsample_prep_condiments
在软件调用这两个 hook 时,插件中的 hook 实现也会一同执行,仿佛这两个函数之前就在软件中一样。
03
使用插件
使用插件需要先安装插件
pip install -e eggsample-spam
重新执行 eggsample
从结果可以看出,在安装插件之后,原有的执行方式得到了新的结果:
-
插件通过 eggsample_add_ingredients 钩子,修改了
self.ingredients
的数据内容 -
插件通过 eggsample_prep_condiments 钩子,修改了
condiments_tray
的数据内容 -
插件通过 eggsample_prep_condiments 返回值,让软件多输出了一行
这个实例是官方文档中提供的,它体现出了 pluggy 的一些特点:
-
插件可以独立开发、维护、安装、更新、卸载
-
插件可以被软件自动调用,并且可以访问和修改软件的自身数据
-
插件在实现 hook 时,参数和返回值是可以省略,并不要求 hookspec 一模一样
首发于公众号:测试开发研习社
原创不易,喜欢请星标+点赞+在看