解析Cucumber JSON测试输出:提取字段并转CSV(支持多语言)
Alright, let's work through converting your Cucumber JSON output to CSV while extracting key fields like name and status. I've put together practical solutions in PHP, Java, and Perl—pick the one that fits your workflow best:
This approach uses built-in PHP functions to read the JSON, traverse its nested structure, and write directly to a CSV file. It includes optional handling for Before hooks if you want to include those results too.
<?php // Read the Cucumber JSON file $jsonContent = file_get_contents("/home/xxx/test1.json"); $cucumberData = json_decode($jsonContent, true); // Initialize CSV file and write header row $csvFile = fopen('cucumber_results.csv', 'w'); fputcsv($csvFile, ['Feature Name', 'Scenario Name', 'Step Name', 'Step Status', 'Step Duration']); // Loop through each feature in the JSON foreach ($cucumberData as $feature) { $featureName = $feature['name']; // Loop through each scenario/element under the feature foreach ($feature['elements'] as $element) { $scenarioName = $element['name']; // Extract step details foreach ($element['steps'] as $step) { $stepName = $step['name']; $stepStatus = $step['result']['status']; $stepDuration = $step['result']['duration']; fputcsv($csvFile, [$featureName, $scenarioName, $stepName, $stepStatus, $stepDuration]); } // Optional: Include Before hook results (remove if not needed) foreach ($element['before'] ?? [] as $hook) { $hookLabel = "Before Hook: " . $hook['match']['location']; $hookStatus = $hook['result']['status']; $hookDuration = $hook['result']['duration']; fputcsv($csvFile, [$featureName, $scenarioName, $hookLabel, $hookStatus, $hookDuration]); } } } fclose($csvFile); echo "CSV generated successfully!"; ?>
For Java, we'll use the Jackson library to parse the JSON (it handles nested structures smoothly) and a custom helper to escape CSV fields properly. First, add the Jackson dependency to your project (Maven example included).
Maven Dependency
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> </dependency>
Java Code
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Iterator; public class CucumberJsonToCsv { public static void main(String[] args) { try { // Load and parse the JSON file ObjectMapper mapper = new ObjectMapper(); JsonNode rootNode = mapper.readTree(new File("/home/xxx/test1.json")); // Set up CSV writer and write header FileWriter csvWriter = new FileWriter("cucumber_results.csv"); csvWriter.append("Feature Name,Scenario Name,Step Name,Step Status,Step Duration\n"); // Iterate through all features Iterator<JsonNode> featureIterator = rootNode.elements(); while (featureIterator.hasNext()) { JsonNode feature = featureIterator.next(); String featureName = feature.get("name").asText(); // Iterate through scenarios/elements Iterator<JsonNode> elementIterator = feature.get("elements").elements(); while (elementIterator.hasNext()) { JsonNode element = elementIterator.next(); String scenarioName = element.get("name").asText(); // Extract step data Iterator<JsonNode> stepIterator = element.get("steps").elements(); while (stepIterator.hasNext()) { JsonNode step = stepIterator.next(); String stepName = step.get("name").asText(); String stepStatus = step.get("result").get("status").asText(); long stepDuration = step.get("result").get("duration").asLong(); csvWriter.append(String.format("%s,%s,%s,%s,%d\n", escapeCsvField(featureName), escapeCsvField(scenarioName), escapeCsvField(stepName), stepStatus, stepDuration)); } // Optional: Include Before hook data if (element.has("before")) { Iterator<JsonNode> hookIterator = element.get("before").elements(); while (hookIterator.hasNext()) { JsonNode hook = hookIterator.next(); String hookLocation = hook.get("match").get("location").asText(); String hookStatus = hook.get("result").get("status").asText(); long hookDuration = hook.get("result").get("duration").asLong(); csvWriter.append(String.format("%s,%s,%s,%s,%d\n", escapeCsvField(featureName), escapeCsvField(scenarioName), escapeCsvField("Before Hook: " + hookLocation), hookStatus, hookDuration)); } } } } csvWriter.flush(); csvWriter.close(); System.out.println("CSV generated successfully!"); } catch (IOException e) { e.printStackTrace(); } } // Helper to escape commas/quotes in CSV fields private static String escapeCsvField(String field) { if (field.contains(",") || field.contains("\"")) { return "\"" + field.replace("\"", "\"\"") + "\""; } return field; } }
Perl uses the JSON module to decode the input and Text::CSV to handle proper CSV formatting (it auto-handles escaping). First, install the required modules via CPAN:
cpan JSON Text::CSV
Perl Code
use strict; use warnings; use JSON; use Text::CSV; # Read the JSON file open my $json_fh, '<', '/home/xxx/test1.json' or die "Can't open JSON file: $!"; my $json_content = do { local $/; <$json_fh> }; close $json_fh; my $cucumber_data = decode_json($json_content); # Set up CSV writer and write header my $csv = Text::CSV->new({ binary => 1, auto_diag => 1 }); open my $csv_fh, '>:encoding(utf8)', 'cucumber_results.csv' or die "Can't open CSV file: $!"; $csv->print($csv_fh, ['Feature Name', 'Scenario Name', 'Step Name', 'Step Status', 'Step Duration']); # Traverse the JSON structure foreach my $feature (@$cucumber_data) { my $feature_name = $feature->{name}; foreach my $element (@{$feature->{elements}}) { my $scenario_name = $element->{name}; # Extract step details foreach my $step (@{$element->{steps}}) { my $step_name = $step->{name}; my $step_status = $step->{result}->{status}; my $step_duration = $step->{result}->{duration}; $csv->print($csv_fh, [$feature_name, $scenario_name, $step_name, $step_status, $step_duration]); } # Optional: Include Before hook results if (exists $element->{before}) { foreach my $hook (@{$element->{before}}) { my $hook_label = "Before Hook: " . $hook->{match}->{location}; my $hook_status = $hook->{result}->{status}; my $hook_duration = $hook->{result}->{duration}; $csv->print($csv_fh, [$feature_name, $scenario_name, $hook_label, $hook_status, $hook_duration]); } } } } close $csv_fh; print "CSV generated successfully!\n";
内容的提问来源于stack exchange,提问作者M Loe

