You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何调用Pytest仅执行报告生成函数而不运行测试用例?

实现仅执行Pytest报告函数并重新生成HTML报告的方案

问题背景

已开发基于Pytest的测试框架,将测试流程与报告函数分离:

  • 测试用例格式:def test_testcase001()
  • 对应报告函数:def reporter_testcase001(meas_file)
    需求:仅指定已有测量文件夹,通过pytest-html重新生成HTML报告,仅执行reporter_开头的报告函数,不运行test_开头的测试用例。

具体实现步骤

1. 添加自定义命令行参数

在conftest.py中添加参数,用于指定已有测量文件夹的根目录:

def pytest_addoption(parser):
    parser.addoption(
        "--measurement-root",
        action="store",
        help="指定已有的测量文件夹根目录,用于重新生成报告"
    )

2. 标记报告函数

给所有reporter_开头的报告函数添加专属标记,方便后续筛选执行:

import pytest

class TestMyCases:
    def test_testcase001(self):
        # 原有测试逻辑
        pass

    @pytest.mark.report_only
    def reporter_testcase001(self, meas_file):
        # 原有报告生成逻辑
        pass

3. 修改自动Fixture逻辑

调整_intermediate_setup_teardown fixture,根据命令行参数判断是否跳过测试执行,直接复用指定的测量文件夹:

import os
import pytest

@pytest.fixture(autouse=True, scope='function')
def _intermediate_setup_teardown(request, overall_setup_teardown, load_parameter_set):
    request.config.test_params = None
    try:
        request.config.test_params = request.node.callspec.params 
    except:
        pass

    # 获取命令行传入的测量根目录
    measurement_root = request.config.getoption("--measurement-root")
    # 判断是否处于仅报告模式
    is_report_only = request.node.get_closest_marker("report_only") is not None
    
    if is_report_only:
        # 仅报告模式:直接匹配对应测量文件夹
        testname = request.function.__name__.replace("reporter_", "")
        if request.config.test_params:
            testname = f'{testname}_{"_".join(map(str, request.config.test_params.values()))}'
        testdir = os.path.join(measurement_root, request.node.cls.__name__, testname)
        request.config.measurement_folder = testdir
        
        yield
        
        # 直接执行当前报告函数
        meas_file = os.path.join(testdir, 'meas.mat')
        if request.config.test_params is None:
            request.function(meas_file)
        else:
            request.function(meas_file, request)
    else:
        # 原有测试执行逻辑
        testname = request.function.__name__ if request.config.test_params is None else f'{request.function.__name__}_{"_".join(map(str, request.config.test_params.values()))}'
        testdir = os.path.join(request.config.result_folder, request.node.cls.__name__, testname )
        os.makedirs(testdir, exist_ok=True)
        
        request.config.measurement_folder = testdir
        setup_test = request.node.cls.setup_test
        if params := request.config.model_params:
            setup_test(params)
        else:
            setup_test() 
        
        yield
        
        meas_file = os.path.join(testdir, 'meas.mat')
        teardown_test = request.node.cls.teardown_test
        teardown_test(meas_file)
        marker = request.node.get_closest_marker('report')
        
        if marker:
            report_name = marker.args[0]
            reporter = getattr(request.node.cls, f'report_{report_name}')
            reporter(meas_file) if request.config.test_params is None else reporter(meas_file, request)

4. 过滤测试用例(可选)

如果需要彻底排除test_开头的用例,在conftest.py中添加收集钩子:

def pytest_collection_modifyitems(config, items):
    measurement_root = config.getoption("--measurement-root")
    if measurement_root:
        # 仅保留带report_only标记的用例
        items[:] = [item for item in items if item.get_closest_marker("report_only") is not None]

5. 适配报告图片生成Hook

确保从指定测量文件夹读取图片,修改钩子逻辑:

import os
from base64 import b64encode

@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, 'extra', [])

    if report.when == 'teardown':
        meas_folder = item._request.config.measurement_folder
        if os.path.exists(meas_folder):
            for dirpath, _, files in os.walk(meas_folder):
                for f in files:
                    if f.endswith('.png'):
                        with open(os.path.join(dirpath, f), 'rb') as img_file:
                            plot64 = b64encode(img_file.read()).decode('utf-8')
                        png_html = f'<img src="data:image/png;base64,{plot64}" width="500" height="500" alt="测试图片">'
                        extra.append(html.extras.html(png_html))
        report.extra = extra

运行命令

执行以下命令即可仅生成报告,不运行测试用例:

pytest --measurement-root=/path/to/your/measurement/folder -m report_only --html=report.html

内容的提问来源于stack exchange,提问作者Ádám Varga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 00:32:46