-
前言:用过pytest的小伙伴应该都知道,pytest之所以功能强大,是因为pytest的插件非常的多。这是插件大多是pytest的使用者所开发的,今天咱们专门来聊聊如何去自己开发Pytest的插件。
-
一:pytest插件的介绍
- pytest框架采用的是插件系统的模式来设计的,pytest运行的所有流程都是基于插件实现的钩子来实现的。一个插件包含一个或多个钩子函数。编写钩子 解释了如何自己编写钩子函数的基础知识和细节。 pytest通过调用插件的指定钩子来实现配置、收集、运行和报告的各个方面:
- 内置插件:从 pytest 的内部_pytest目录加载。
- 外部插件:通过 setuptools 入口点发现的模块
- conftest.py 插件:在测试目录中自动发现的模块
- 原则上,每个钩子调用都是一个1:NPython 函数调用,其中N是给定钩子的已注册实现函数的数量。所有钩子都遵循pytest_前缀命名约定,使其易于区分和查找。
- pytest框架采用的是插件系统的模式来设计的,pytest运行的所有流程都是基于插件实现的钩子来实现的。一个插件包含一个或多个钩子函数。编写钩子 解释了如何自己编写钩子函数的基础知识和细节。 pytest通过调用插件的指定钩子来实现配置、收集、运行和报告的各个方面:
-
二:pytest启动时插件发现顺序
- pytest通过以下方式在工具启动时加载插件模块:
- 1、通过扫描命令行中的选项并阻止加载该插件(即使是内置插件也可以通过这种方式阻止)。这发生在正常的命令行解析之前。-p no:name
- 2、通过加载所有内置插件。
- 3、通过扫描命令行选项并加载指定的插件。这发生在正常的命令行解析之前。-p name
- 4、通过加载通过setuptools 入口点注册的所有插件。
- 5、通过加载通过PYTEST_PLUGINS环境变量
- 6、通过加载conftest.py命令行调用推断的所有文件:
- 6.1:如果没有指定测试路径,则使用当前目录作为测试路径
- 6.2:如果存在,则加载conftest.py并test*/conftest.py相对于第一个测试路径的目录部分。加载文件后conftest.py ,加载其 pytest_plugins变量中指定的所有插件(如果存在)。
- 请注意,pytest 在工具启动时不会conftest.py在更深的嵌套子目录中找到文件。conftest.py将文件保存在顶级测试或项目根目录中通常是个好主意。
- 7、通过递归加载 文件中pytest_plugins变量指定的所有插件conftest.py。
-
三:插件开发的流程
- 明确需求:开发一个什么功能的插件?
- 分析需求:这个功能在pytest执行的那个阶段执行?
- 找出实现需要用到的钩子函数
- 在conftest.py中定义对应的钩子函数实现相关的功能
-
四:案例:
- 我们现在实现的功能:
- 1.把测试的结果.改成Y,F改成x
- 2.命令行加个--change参数开关,默认不开启,当加上参数--change on的时候才生效
- 1、先创建一个工程,目录如下:
- setup.py 在安装python的相关模块和库时,我们一般使用pip install 模块名或者python setup.py install,前者是在线安装,会安装该包的相关依赖包; 后者是下载源码包然后在本地安装,不会安装该包的相关依赖包
- README.rst README 文档,告诉用户如何使用你的插件,具体能实现什么功能
- pytest_change_report.py 也就是之前conftest.py里面写的hook函数实现的功能
- tests 用于测试本插件的相关功能,属于自测的内容
- tests/conftest.py 开启需要的插件pytester
- tests/test_change_report.py 测试插件的代码
- 2、pytest_change_report.py中代码
- 我们现在实现的功能:
import pytest
def pytest_addoption(parser):
parser.addoption(
"--change",
action="store",
default="off",
help="'Default 'off' for change, option: on or off"
)
def pytest_report_teststatus(report, config):
'''turn . into √,turn F into x, turn E into 0'''
if config.getoption("--change") == "on":
if report.when == 'call' and report.failed:
return (report.outcome, 'x', 'failed')
if report.when == 'call' and report.passed:
return (report.outcome, 'Y', 'passed')
- 3、setup.py
from setuptools import setup
setup(
name='pytest-change-report',
url='https://github.com/yoyoketang/pytest-change-report',
version='1.0',
author="xwl",
author_email='[email protected]',
description='turn . into Y,turn F into x',
long_description='print result on terminal turn . into Y,turn F into x using hook',
classifiers=[
'Framework :: Pytest',
'Programming Language :: Python',
'Topic :: Software Development :: Testing',
'Programming Language :: Python :: 3.6',
],
license='proprietary',
py_modules=['pytest_change_report'],
keywords=[
'pytest', 'py.test', 'pytest-change-report',
],
install_requires=[
'pytest'
],
entry_points={
'pytest11': [
'change-report = pytest_change_report',
]
}
)
-
4、最后需要写个 README.rst 使用教程文档,这样你写的插件就能被其它小伙伴学习和使用了。
-
五:打包和上传
- 当有一天你公司的小伙伴觉得你写的还不错,或者更多的小伙伴想要你这个功能,于是你就想着放到github上,写成一个插件,方便小伙伴使用pip去安装。如果我们想通过 pip install packages 这种方式安装的话,需上传到 pypi 仓库
- 1、上传github
- 从GitHub源码安装
- pip install git+https://github.com/1069181618/pytest_change_report.git
- 从GitHub源码安装
- 2、上传pypi,未完待续