sweetchuck/junit-merger-cli
CLI tool to merge multiple JUnit XML reports into a single file. Reads file paths from stdin or arguments, outputs to stdout or a specified file. Supports DOM-based and fast substring handlers, with an option to recalculate testsuite counts.
--parallel) into a single JUnit XML file for unified reporting in tools like SonarQube, Codecov, or Jenkins. Directly addresses test reliability and debugging efficiency in Laravel projects.--parallel --distribute).--parallel) and needing a single JUnit report for CI tools.spatie/laravel-test-failures with extended schemas).test-results).substr handler risks malformed output.*"This CLI tool solves a critical bottleneck in our test automation pipeline: merging fragmented JUnit reports from parallelized test runs into a single, standardized output. It’s a turnkey solution that:
With a one-liner integration in our CI pipeline, we can ensure test reporting consistency across environments—directly supporting our goals for [QA efficiency/automation/observability]. The risk is minimal: it’s a battle-tested PHP tool with no Laravel-specific dependencies."*
*"The junit-merger-cli package lets us consolidate JUnit XML files from parallel Pest/PHPUnit runs (e.g., --parallel --distribute) into a single file for tools like SonarQube or Jenkins. Here’s why it’s a no-brainer:
find or direct file arguments. Example:
# Merge all JUnit files in a directory and pipe to SonarQube
find tests/_output -name '*.xml' | junit-merger merge:files > merged-report.xml
dom_read_write (accurate, recalculates test suite stats).substr (fast, for identical-format files).shell_exec or wrapped in an Artisan command.Trade-offs:
dom_read_write may be slower for 1000+ files (benchmark with our test suite).Next Steps:
php artisan junit:merge).This avoids reinventing the wheel while keeping our workflows lean."*
*"If you’re running parallel tests (Pest/PHPUnit --parallel) and struggling with scattered JUnit reports, this tool is your CI lifesaver. Here’s how to use it in Laravel:
composer require sweetchuck/junit-merger-cli
# Option 1: Pipe from `find`
find storage/logs/junit -name '*.xml' | vendor/bin/junit-merger merge:files > merged.xml
# Option 2: Direct files (with handler)
vendor/bin/junit-merger merge:files --handler='dom_read_write' file1.xml file2.xml --output-file=merged.xml
// app/Console/Commands/MergeJUnitReports.php
class MergeJUnitReports extends Command {
protected $signature = 'junit:merge {--output= : Output file}';
public function handle() {
$files = glob(storage_path('logs/junit/*.xml'));
$output = $this->option('output') ?: storage_path('logs/junit/merged.xml');
shell_exec("php vendor/bin/junit-merger merge:files " . implode(' ', $files) . " > $output");
}
}
Then run:
php artisan junit:merge --output=storage/logs/junit/report.xml
Pro Tip: Use --handler='substr' for speed if your test files are identically formatted (e.g., from the same PHPUnit run). Use dom_read_write for accuracy (recalculates test counts).
Debugging: If the merged XML looks wrong, check:
SimpleXML can validate).dom_read_write for strict parsing).How can I help you explore Laravel packages today?