I am writing test cases using cucumber, and testNG using Java 17.
We created multiple feature files and for each feature, we have a separate runner class.
Confucurtion of the runner class looks as below:
@CucumberOptions(features = {"src/test/resources/features/wallet/A.feature"},
glue = {"com.test.a"},
plugin = {"pretty", "json:build/cucumber-reports/a.json"})
@Test(groups = {"A", "regression"}, alwaysRun = true)
public class RunnerA extends AbstractTestNGCucumberTests {
}
@CucumberOptions(features = {"src/test/resources/features/wallet/B.feature"},
glue = {"com.test.b"},
plugin = {"pretty", "json:build/cucumber-reports/b.json"})
@Test(groups = {"B", "regression"}, alwaysRun = true)
public class RunnerB extends AbstractTestNGCucumberTests {
}
When I run the test case it generates 2 JSON files in cucumber-reports
folder as a.json
and b.json
.
How can I merge these two json files in one single json file ie. report.json
I am using gradle 7
as a build tool with cucumber 7.11.0
I resolved this by writing a custom gradle task.
Here is my solution:
Gradle task:
task aggregatReport(type: JavaExec) {
println("Running aggregatReport task")
description 'Combine multiple cucumber report json file into one json file'
classpath sourceSets.main.runtimeClasspath
mainClass = "com.ReportAggregator"
def reportFolderPath = "./build/cucumber-reports/";
File file = file(reportFolderPath);
args file.toPath().toAbsolutePath().toString()
}
The code:
public class ReportAggregator {
public static void main(String[] args) throws IOException {
System.out.println("ReportAggregator with argument -> " + Arrays.toString(args));
ObjectMapper objectMapper = new ObjectMapper();
File reportFolder = new File(args[0]);
System.out.println("Report folder -> " + reportFolder.isDirectory() + " " + reportFolder.exists());
List<Path> reportFiles = Files.walk(reportFolder.toPath()).filter(file -> file.toFile().getName().endsWith(".json")).toList();
List<Map<String, Object>> finalReportList = new ArrayList<>();
if (CollectionUtil.isNotEmpty(reportFiles)) {
System.out.println("Total report file ->" + reportFiles.size());
reportFiles.forEach(path -> {
try {
String jsonString = FileUtils.readFileToString(path.toFile(), Charset.defaultCharset());
TypeReference<List<Map<String, Object>>> typeRef = new TypeReference<>() {
};
List<Map<String, Object>> hashMaps = objectMapper.readValue(jsonString, typeRef);
finalReportList.addAll(hashMaps);
} catch (IOException e) {
System.err.println("Can not read file -> " + path.toFile().getAbsolutePath());
}
});
if (CollectionUtil.isNotEmpty(finalReportList)) {
String finalReportFileName = reportFolder.getAbsolutePath() + "/final.json";
File finalReportFile = new File(finalReportFileName);
if (finalReportFile.exists()) {
boolean delete = finalReportFile.delete();
System.out.println("File is deleted -> " + delete);
}
FileUtils.writeStringToFile(finalReportFile, objectMapper.writeValueAsString(finalReportList), Charset.defaultCharset());
System.out.println("Report file created");
} else {
System.err.println("Empty report is created");
throw new ReportException("Empty report created");
}
} else {
throw new ReportException("No report file found under folder ->" + reportFolder.getAbsolutePath());
}
}
}
and gralde task dependency settings:
test {
println("Running test task")
useTestNG() {
suites 'src/test/testng.xml'
}
finalizedBy aggregatReport
}
task importJunitResultsToXrayCloud() {
dependsOn 'test'
description 'Imports Cucumber test results to Xray Test Management for Jira Cloud.'
doLast {
//code to upload report
}
}
and to upload report just run ./gradlew importJunitResultsToXrayCloud