测试框架pytest教程(6)钩子函数hook开发pytest插件

pytest hook 函数也叫钩子函数,pytest 提供了大量的钩子函数,可以在用例的不同生命周期自动调用。 比如,在测试用例收集阶段,可利用 hook 函数修改测试用例名称的编码。

pytest的hook是基于Python的插件系统实现的,使用特定的命名规范和装饰器来定义钩子函数。你可以在pytest插件或conftest文件中定义这些钩子函数。

pytest 可以识别到三种插件

内置插件:从 pytest 内部 _pytest 目录加载的插件

外部插件:通过 pip 安装的插件(比如: pip install pytest-ordering )。

conftest.py 插件:测试目录中的 conftest.py 加载

常用的pytest钩子函数

  1. `pytest_configure(config)`: 在pytest启动时调用,可用于注册自定义标记、插件等。

  2. `pytest_collection_modifyitems(config, items)`: 测试收集阶段调用,可以修改、筛选或排序收集到的测试项。

  3. `pytest_runtest_protocol(item, nextitem)`: 在运行每个测试用例之前和之后调用,可以执行初始化、清理或自定义测试流程等操作。

  4. `pytest_report_teststatus(report)`: 在测试用例执行后调用,可用于自定义测试结果报告。

  5. `pytest_terminal_summary(terminalreporter)`: 在测试会话结束时调用,可用于生成自定义的测试总结报告。

通过使用这些钩子函数,你可以在pytest的不同阶段添加自己的逻辑和行为。这使得您可以自定义测试收集、执行、报告等方面,以满足特定的需求。

有许多其他的pytest钩子函数可以用于不同的目的和扩展。你可以在pytest的官方文档中查找完整的钩子函数列表以及每个钩子的详细说明和示例。

开发插件

pytest 提供了大量的 hook 函数,执行过程中几乎所有的行为都是可以定制的。那么,pytest 可以改写哪 些行为呢? 文字版 pytest hook 执行顺序:

root
└── pytest_cmdline_main
├── pytest_plugin_registered
├── pytest_configure
│ └── pytest_plugin_registered
├── pytest_sessionstart
│ ├── pytest_plugin_registered
│ └── pytest_report_header
├── pytest_collection
│ ├── pytest_collectstart
│ ├── pytest_make_collect_report
│ │ ├── pytest_collect_file
│ │ │ └── pytest_pycollect_makemodule
│ │ └── pytest_pycollect_makeitem
│ │ └── pytest_generate_tests
│ │ └── pytest_make_parametrize_id
│ ├── pytest_collectreport
│ ├── pytest_itemcollected
│ ├── pytest_collection_modifyitems
│ └── pytest_collection_finish
│ └── pytest_report_collectionfinish
├── pytest_runtestloop
│ └── pytest_runtest_protocol
│ ├── pytest_runtest_logstart
│ ├── pytest_runtest_setup
│ │ └── pytest_fixture_setup
│ ├── pytest_runtest_makereport
│ ├── pytest_runtest_logreport
│ │ └── pytest_report_teststatus
│ ├── pytest_runtest_call
│ │ └── pytest_pyfunc_call
│ ├── pytest_runtest_teardown
│ │ └── pytest_fixture_post_finalizer
│ └── pytest_runtest_logfinish
├── pytest_sessionfinish
│ └── pytest_terminal_summary
└── pytest_unconfigure

可以利用 pytest hook 强大的功能开发出自己的插件。

hook和fixture的区别

在pytest中,Hooks(钩子)和Fixtures(装置)是两个不同的概念。

Hooks(钩子)是pytest提供的一组钩子函数,用于自定义和扩展测试流程。钩子函数在特定的时间点被调用,并允许你插入自定义的代码来修改、补充或拦截测试操作,比如定制报告、自定义收集规则、执行前/后的初始化和清理等。Hooks通常由插件或conftest文件定义,并使用特定的命名规范和装饰器进行标记。使用hooks可以灵活地定制和扩展pytest的行为。

Fixtures(装置)是pytest的一项功能,用于管理测试用例的前置和后置操作。Fixture可以被看作为测试用例的准备和清理工作,并且可以在多个测试用例之间共享数据和资源。Fixture函数使用`@pytest.fixture`装饰器进行标记,并在测试函数的参数中使用。当测试函数需要使用该装置时,fixture函数将被自动执行并提供必要的数据和资源。Fixture可以执行一些初始化操作,为测试用例提供必要的数据,以及在测试结束后进行清理工作。使用fixture可以提高代码的复用性和可维护性,并减少测试用例之间的重复工作。

总结起来,Hooks允许你定制和扩展测试流程,而Fixtures则用于管理测试用例的前置和后置操作,并提供必要的数据和资源。Hooks是用于自定义pytest的整体行为,而Fixtures是用于测试用例级别的准备和清理工作。两者可以一起使用,以实现更高级别的自定义和测试管理。

pytest_collection_modifyitems

python 复制代码
def pytest_collection_modifyitems(
    session: "Session", config: "Config", items: List["Item"]
) -> None:
    """Called after collection has been performed. May filter or re-order
    the items in-place.

    :param pytest.Session session: The pytest session object.
    :param pytest.Config config: The pytest config object.
    :param List[pytest.Item] items: List of item objects.
    """

可以看到该方法在用例收集后执行,可以筛选或者对用例执行顺序进行修改。

插件开发-筛选收集到的用例

当你想要自定义收集阶段中的测试项时,可以使用`pytest_collection_modifyitems`钩子函数。这个钩子函数在pytest的测试收集过程中被调用,允许你对收集到的测试项进行修改、筛选或排序。

下面是一个使用`pytest_collection_modifyitems`的例子,假设你希望在测试收集阶段中只运行有特定标记的测试用例(比如`smoke`标记),在根目录的conftest.py中添加如下方法:

python 复制代码
def pytest_collection_modifyitems(config, items):
    marked_items = []
    unmarked_items = []

    # 将有"smoke"标记的测试项放入marked_items列表,其他放入unmarked_items列表
    for item in items:
        if 'smoke' in item.keywords:
            marked_items.append(item)
        else:
            unmarked_items.append(item)

    # 只保留有"smoke"标记的测试项
    items[:] = marked_items

    # 打印被移除的未标记项的名称
    for item in unmarked_items:
        print(f"Skipping unmarked test: {item.nodeid}")

在上述代码中,`pytest_collection_modifyitems`钩子函数接收两个参数:`config`表示pytest的配置对象,`items`是测试收集阶段收集到的所有测试项(测试用例)的列表。我们首先遍历每个测试项,将有"smoke"标记的项放入`marked_items`列表,其他项放入`unmarked_items`列表。然后,我们通过将`items`列表替换为`marked_items`列表,实现只保留有"smoke"标记的测试项。最后,我们遍历`unmarked_items`列表,打印被移除的未标记项的名称作为提示信息。

可以看到test_b被跳过

插件开发-改写用例名称编码

测试用例如下

python 复制代码
@pytest.mark.parametrize("name",["哈利","赫敏"])
def test_encode(name):
    print(name)

运行时会出现乱码

在conftest.py中添加如下方法

python 复制代码
def pytest_collection_modifyitems(config, items):
    for item in items:
        item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')

再次运行可以看到节点id显示为中文了。

插件打包

软件测试 | Pytest测试框架之插件开发_pytest_hook_函数

相关推荐
Simp1e_a1 小时前
最大转矩电流比(MTPA)
科技·自动化·硬件工程·能源·制造
PieroPc5 小时前
Python 自动化 打开网站 填表登陆 例子
运维·python·自动化
VinciYan6 小时前
基于Jenkins+Docker的自动化部署实践——整合Git与Python脚本实现远程部署
python·ubuntu·docker·自动化·jenkins·.net·运维开发
开源优测6 小时前
深度解析 Pytest 中的 conftest.py
pytest
一条测试老狗7 小时前
【UI自动化】从WebDriver看Selenium与Appium的底层关联
selenium·appium·自动化
Linux运维技术栈8 小时前
Ansible(自动化运维)环境搭建及ansible-vault加密配置
运维·自动化·ansible
天天要nx13 小时前
D105【python 接口自动化学习】- pytest进阶参数化用法
python·pytest
沛沛老爹17 小时前
什么是 DevOps 自动化?
大数据·ci/cd·自动化·自动化运维·devops
永恒,怎么可能17 小时前
关于博客系统的自动化功能测试报告
自动化·测试
AI慧聚堂19 小时前
自动化 + 人工智能:投标行业的未来是什么样的?
运维·人工智能·自动化