1,什么是hooks?
1,在 pytest 中,hooks 是一种特殊的机制,允许用户插入自己的逻辑到测试执行的不同阶段。通过使用 hooks,开发者可以对测试执行过程进行定制化,比如修改测试对象、处理测试结果、配置测试环境等。
2,pytest的钩子(hooks)通常是写在conftest.py文件中的。这个文件用于存放测试配置、固件(fixtures)以及钩子函数等,pytest会自动识别该文件并加载其中的配置和代码。
2,pytest 常见的 hooks
- pytest_configure(config): 在测试运行开始之前调用,可以用来设置或修改配置信息。
- pytest_unconfigure(config): 在所有测试执行完毕后调用,可以用来执行清理工作。
- pytest_collect_file(path, parent): 当收集测试文件时调用,可以用来过滤或修改收集到的文件。
- pytest_collection_modifyitems(session, config, items): 在收集完测试项后调用,可以用来重新排序或修改测试项。
- pytest_itemcollected(item): 每当一个测试项被收集时调用。
- pytest_runtest_setup(item): 在每个测试项运行之前调用,可以用来准备测试环境。
- pytest_runtest_call(item): 在执行测试项的调用阶段时调用。
- pytest_runtest_teardown(item, nextitem): 在每个测试项运行之后调用,可以用来清理测试环境。
- pytest_addoption(parser): 用于添加命令行选项。
- pytest_report_header(config): 可以用来添加自定义头部信息到测试报告中。
- pytest_exception_interact(node, call, report): 当测试失败时调用,可以用来处理异常或进行调试。
3,项目实战
pytest 中使用不同的钩子(hooks)来定制测试过程和测试报告
下面展示一些 内联代码片
。
代码示例:
import os
import pytest
import time
from py.xml import html
def pytest_addoption(parser):
"""
向 pytest 添加自定义的命令行选项。
这使得在命令行运行测试时可以传递额外的参数,如服务器环境、设备型号和项目名称。
"""
parser.addoption("--server", action="store", help="服务器环境")
parser.addoption("--project", action="store", help="项目名")
@pytest.mark.optionalhook
def pytest_html_results_summary(prefix):
"""
这个钩子允许你向报告的摘要部分添加自定义内容,如测试团队的信息。
:param prefix:
:return:
"""
prefix.extend([html.p("所属部门")])
prefix.extend(([html.p("测试人员")]))
def pytest_configure(config):
"""
使用 pytest_configure 钩子函数来根据环境变量中的值定制化测试报告的元数据。
获取超时接口
:return:
"""
all_timeout_count = os.environ.get('all_timeout_count')
timeout = os.environ.get('timeout_ts')
if timeout:
config._metadata[f"响应时长超过 {timeout}s 的接口数"] = all_timeout_count
else:
config._metadata["超过预期响应时长的接口请求数"] = all_timeout_count
"""
这两个钩子函数是与 pytest-html 插件一起使用的,用于自定义生成的 HTML 测试报告中的表格。
pytest-html 是一个流行的 pytest 插件,它可以生成一个包含测试结果详情的 HTML 报告。
这些钩子允许你修改测试结果表格的头部(header)和每一行(row)的内容和格式。
"""
def pytest_html_results_table_header(cells):
"""
此钩子用于定制测试结果表格的头部。cells 参数是一个列表,包含表格头部的每个单元格。
通过修改这个列表,你可以改变表头的结构和内容。
:param cells:
:return:
"""
cells.insert(1, html.th('Description'))
cells.insert(3, html.th('Time', class_='sortable time', col='time'))
cells.pop()
def pytest_html_results_table_row(report, cells):
"""
在第二个位置插入一个新的单元格,显示测试的描述。
report.description 需要在其他地方被定义,例如在 pytest_runtest_makereport 钩子中。
:param report:
:param cells:
:return:
"""
cells.insert(1, html.td(report.description))
cells.insert(3, html.td(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), class_='col-time'))
cells.pop()
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
"""
这个个钩子用于在测试执行后生成测试报告。示例中使用它来为每个测试项添加一个描述,
该描述来自测试函数的文档字符串。
:param item:
:return:
"""
outcome = yield
report = outcome.get_result()
report.description = str(item.function.__doc__)
总结
钩子函数通常定义在 conftest.py 文件中,这样 pytest 可以自动发现并应用这些钩子。
钩子的使用可以极大地增强 pytest 的灵活性和功能性,但需要注意正确地使用它们以避免潜在的问题。
通过灵活使用这些钩子,pytest 用户可以构建一个高度定制化的测试框架,以满足特定项目的需求。