在pytest中,"hook"是用于自定义和扩展测试流程的机制。它允许你在特定时间点插入自己的代码,以便对测试进行修改、补充或拦截。
pytest的hook是基于Python的插件系统实现的,使用特定的命名规范和装饰器来定义钩子函数。你可以在pytest插件或conftest文件中定义这些钩子函数。
常用的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的官方文档中查找完整的钩子函数列表以及每个钩子的详细说明和示例。
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
当你想要自定义收集阶段中的测试项时,可以使用`pytest_collection_modifyitems`钩子函数。这个钩子函数在pytest的测试收集过程中被调用,允许你对收集到的测试项进行修改、筛选或排序。
下面是一个使用`pytest_collection_modifyitems`的例子,假设你希望在测试收集阶段中只运行有特定标记的测试用例(比如`smoke`标记):
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被跳过