请求在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
相关产品推荐
相关产品推荐

