Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Junit Merger Cli Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the package via Composer:
    composer require sweetchuck/junit-merger-cli --dev
    
  2. Locate JUnit XML files generated by Laravel/Pest/PHPUnit (e.g., storage/logs/junit/*.xml).
  3. Run the merger with stdin input (e.g., from find):
    find storage/logs/junit -name '*.xml' | vendor/bin/junit-merger merge:files
    
    Or with direct file arguments:
    vendor/bin/junit-merger merge:files file1.xml file2.xml > merged.xml
    

First Use Case

Consolidate parallel test reports in CI:

# .github/workflows/tests.yml
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: vendor/bin/pest --parallel --distribute=4
      - run: find storage/logs/junit -name '*.xml' | vendor/bin/junit-merger merge:files > merged-report.xml
      - uses: actions/upload-artifact@v3
        with:
          name: junit-report
          path: merged-report.xml

Implementation Patterns

Workflows

  1. CI Pipeline Integration:

    • Pre-merge: Collect files from parallel test runs (e.g., Pest --parallel).
    • Merge: Use dom_read_write for accurate test suite stats:
      find tests/_output -name '*.xml' | vendor/bin/junit-merger merge:files --handler='dom_read_write' > report.xml
      
    • Post-merge: Upload to SonarQube/Codecov:
      sonar-scanner -Dsonar.junit.reportPaths=report.xml
      
  2. Artisan Command Wrapper (for Laravel-native use):

    // app/Console/Commands/MergeJUnitReports.php
    class MergeJUnitReports extends Command {
        protected $signature = 'junit:merge
            {--output= : Output file path}
            {--handler=dom_read_write : Merge handler}';
    
        public function handle() {
            $files = glob(storage_path('logs/junit/*.xml'));
            $output = $this->option('output') ?? storage_path('logs/junit/merged.xml');
            $handler = $this->option('handler');
    
            $command = "vendor/bin/junit-merger merge:files --handler=$handler " . implode(' ', $files) . " > $output";
            shell_exec($command);
    
            $this->info("Merged {$files} into $output");
        }
    }
    

    Usage:

    php artisan junit:merge --output=report.xml --handler=dom_read
    
  3. Dynamic File Discovery:

    • Use Laravel’s Storage facade to find files:
      use Illuminate\Support\Facades\Storage;
      
      $files = Storage::disk('local')->files('logs/junit');
      

Integration Tips

  • Handler Selection:
    • Use dom_read_write for accuracy (recalculates <testsuite> attributes like tests, failures).
    • Use substr for speed (assumes identical file formats, e.g., from same PHPUnit version).
  • Output Redirection:
    • Prefer --output-file for clarity:
      vendor/bin/junit-merger merge:files --output-file=report.xml file1.xml file2.xml
      
  • Validation:
    • Pre-validate XML with SimpleXML:
      $xml = simplexml_load_file($file);
      if ($xml === false) throw new \RuntimeException("Invalid JUnit XML: $file");
      

Gotchas and Tips

Pitfalls

  1. XML Schema Inconsistencies:

    • Issue: Input files with custom PHPUnit extensions (e.g., <custom-tag>) may break merging.
    • Fix: Use dom_read_write or pre-process files with DOMDocument to normalize schemas.
  2. Test ID Collisions:

    • Issue: If parallel test runs use identical test IDs, merged reports may show duplicate entries.
    • Fix: Configure Pest/PHPUnit to use unique test IDs (e.g., include class name):
      // Pest.php
      $this->uniqueTestIds = true;
      
  3. Performance with Large Files:

    • Issue: dom_read_write recalculates attributes, which can be slow for >500 files.
    • Fix: Benchmark and switch to substr if files are format-identical.
  4. Shell Access Limitations:

    • Issue: Some Laravel environments (e.g., serverless) restrict shell_exec.
    • Fix: Fork the junit-merger library and use it directly in PHP:
      use Sweetchuck\JUnitMerger\Merger;
      $merger = new Merger();
      $mergedXml = $merger->merge([$file1, $file2]);
      
  5. Handler-Specific Quirks:

    • substr: Fails if files have different <testsuites> tag positions.
    • dom_read: Output may have duplicate attributes if not using dom_read_write.

Debugging

  • Log Input/Output:
    vendor/bin/junit-merger merge:files file1.xml file2.xml | tee merged.xml
    
  • Validate Merged XML:
    $mergedXml = simplexml_load_file('merged.xml');
    if ($mergedXml->xpath('//testsuite/@tests') === []) {
        throw new \RuntimeException("Merged report has no test cases!");
    }
    
  • Check Exit Codes: The CLI returns 1 on failure (e.g., invalid XML). Capture this in Laravel:
    $exitCode = shell_exec($command . ' 2>&1', $output);
    if ($exitCode !== 0) {
        throw new \RuntimeException("Merge failed: " . $output);
    }
    

Extension Points

  1. Custom Handlers:

    • Extend the junit-merger library to add a Laravel-specific handler (e.g., integrates with Pest’s test events).
  2. Pre/Post-Processing:

    • Use Laravel’s events to transform XML before/after merging:
      // app/Providers/AppServiceProvider.php
      public function boot() {
          Event::listen('junit.merged', function ($mergedXml) {
              // Add custom attributes or filter tests
          });
      }
      
  3. Queue-Based Merging:

    • For large-scale merging, dispatch jobs to Laravel Queues:
      MergeJUnitJob::dispatch($files)->onQueue('junit-merging');
      

Config Quirks

  • Handler Priorities: The CLI defaults to dom_read if no handler is specified. Explicitly set it:
    vendor/bin/junit-merger merge:files --handler=dom_read_write file1.xml file2.xml
    
  • Memory Limits: Increase PHP memory for large merges:
    php -d memory_limit=512M vendor/bin/junit-merger merge:files ...
    
  • Windows Compatibility: Use forward slashes in paths or escape backslashes:
    vendor/bin/junit-merger merge:files "C:/path/to/file1.xml" "C:/path/to/file2.xml"
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle