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

请求在Runner类中添加结果合并方法以适配CI/CD流水线报告需求

解决方案:合并Karate测试结果并生成统一报告

Karate的Results类不支持直接通过+运算符合并,但你可以通过聚合测试统计数据和合并报告文件的方式实现需求,既不用编写多份feature文件,也无需在测试逻辑中添加账号属性相关的条件判断,完全适配CI/CD流水线执行全量回归测试的场景。

1. 聚合测试统计数据

Karate的Results类包含了测试核心统计信息(失败数、错误信息等),你可以手动聚合多个Results对象的统计值,替代直接合并对象的操作:

// 在EquipmentRunner类中添加统计聚合逻辑
private static int calculateTotalFailCount(List<Results> resultsList) {
    return resultsList.stream().mapToInt(Results::getFailCount).sum();
}

private static String combineErrorMessages(List<Results> resultsList) {
    return resultsList.stream()
            .map(Results::getErrorMessages)
            .filter(msg -> msg != null && !msg.isEmpty())
            .collect(Collectors.joining(System.lineSeparator()));
}

2. 合并Cucumber报告文件

每个Runner实例会生成独立的报告文件,你需要合并这些文件后再生成统一的最终报告:

2.1 合并Cucumber JSON报告

先收集所有Runner生成的cucumber.json文件,合并后再生成统一HTML报告:

private static void mergeAndGenerateReport(List<String> reportDirs, String targetDir) throws IOException {
    File targetDirFile = new File(targetDir);
    if (!targetDirFile.exists()) {
        targetDirFile.mkdirs();
    }

    ObjectMapper mapper = new ObjectMapper();
    List<Object> allTestFeatures = new ArrayList<>();

    // 收集所有JSON报告内容
    for (String dir : reportDirs) {
        File jsonFile = new File(dir, "cucumber.json");
        if (jsonFile.exists()) {
            List<Object> features = mapper.readValue(jsonFile, new TypeReference<List<Object>>() {});
            allTestFeatures.addAll(features);
        }
    }

    // 写入合并后的JSON文件
    File mergedJson = new File(targetDirFile, "cucumber.json");
    mapper.writerWithDefaultPrettyPrinter().writeValue(mergedJson, allTestFeatures);

    // 基于合并后的JSON生成统一HTML报告
    com.intuit.karate.ReportGenerator.generateReport(mergedJson.getAbsolutePath(), new HashMap<>(), targetDirFile);
}

3. 修改测试方法实现完整逻辑

调整你的测试代码,关闭单个Runner的HTML报告生成(避免重复),然后执行聚合和合并操作:

public class EquipmentRunner {

    private static final String serviceName = "EquipmentService";
    private static final Integer cores = Runtime.getRuntime().availableProcessors();

    @Test
    public void testParallel() throws IOException {
        Results baseAccountResults = Runner
            .path("classpath:net/charter/equipment/test/api/domain/v1/Equipment_GET.feature")
            .tags("@regression", "~@standarduser")
            .karateEnv("dev_smb")
            .outputCucumberJson(true)
            .outputHtmlReport(false) // 关闭单个报告生成,统一合并后生成
            .outputJunitXml(true)
            .systemProperty("karate.dsRow", "1")
            .parallel(cores);

        Results coamAccountResults = Runner
            .path("classpath:net/charter/equipment/test/api/domain/v1/Equipment_GET.feature")
            .tags("@modem", "~@standarduser")
            .karateEnv("dev_smb")
            .outputCucumberJson(true)
            .outputHtmlReport(false)
            .outputJunitXml(true)
            .systemProperty("karate.dsRow", "8")
            .parallel(cores);

        Results nonCompliantAccountResults = Runner
            .path("classpath:net/charter/equipment/test/api/domain/v1/Equipment_GET.feature")
            .tags("@nonCompliant")
            .karateEnv("dev_smb")
            .outputCucumberJson(true)
            .outputHtmlReport(false)
            .outputJunitXml(true)
            .systemProperty("karate.username", "testCompliance")
            .systemProperty("karate.password", "password")
            .parallel(cores);

        // 收集所有测试结果
        List<Results> allResults = Arrays.asList(baseAccountResults, coamAccountResults, nonCompliantAccountResults);
        
        // 聚合统计数据并断言
        int totalFailures = calculateTotalFailCount(allResults);
        String combinedErrors = combineErrorMessages(allResults);
        assertEquals(0, totalFailures, combinedErrors);

        // 合并并生成统一报告
        List<String> reportDirs = allResults.stream().map(Results::getReportDir).collect(Collectors.toList());
        mergeAndGenerateReport(reportDirs, "target/karate-unified-reports");
    }

    // 放入前面定义的calculateTotalFailCount、combineErrorMessages、mergeAndGenerateReport方法
}

关键注意事项

  • 关闭单个Runner的outputHtmlReport(true),避免生成多份独立HTML报告,改为合并JSON后统一生成。
  • JUnit XML报告可直接在CI/CD工具中批量收集(主流CI工具均支持),无需额外合并。
  • 该方案完全基于Runner配置实现多账号场景测试,无需修改feature文件或添加条件逻辑,适配全量回归测试需求。

内容的提问来源于stack exchange,提问作者mike

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 02:27:05