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

Code Coverage Checker Laravel Package

handcraftedinthealps/code-coverage-checker

CLI tool to enforce PHPUnit code coverage thresholds. Generate a coverage.php report, then check line/class/method coverage against a minimum percentage, optionally limited to specific directories—ideal for CI to fail builds when coverage drops.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package in your Laravel project:

    composer require --dev handcraftedinthealps/code-coverage-checker
    
  2. Generate a coverage report during PHPUnit execution:

    phpunit --coverage-php Tests/reports/coverage.php
    

    Ensure the Tests/reports/ directory exists and is writable.

  3. Run the checker in your CI/CD pipeline or local workflow:

    vendor/bin/code-coverage-checker Tests/reports/coverage.php "line" "90.0"
    

    Replace "line" with "class" or "method" as needed, and adjust the threshold (e.g., "90.0").


First Use Case: Enforcing Coverage in CI

Add this to your phpunit.xml or CI script (e.g., GitHub Actions):

<!-- phpunit.xml -->
<phpunit>
    <listeners>
        <listener class="\PHPUnit\TextUI\Command" file="--coverage-php=Tests/reports/coverage.php"/>
    </listeners>
</phpunit>

Then, in your CI script:

phpunit
vendor/bin/code-coverage-checker Tests/reports/coverage.php "line" "90.0" || exit 1

This fails the build if coverage drops below 90%.


Key Files to Review

  • Tests/reports/coverage.php: Generated by PHPUnit; required for the checker.
  • vendor/bin/code-coverage-checker: CLI tool for validation.
  • phpunit.xml: Configure coverage generation (e.g., --coverage-clover or --coverage-php).

Implementation Patterns

Workflow: Integrating into Laravel Tests

  1. Configure PHPUnit in phpunit.xml:

    <phpunit>
        <coverage>
            <include>
                <directory>./app</directory>
                <directory>./src</directory>
            </include>
            <exclude>
                <directory>./tests</directory>
            </exclude>
        </coverage>
        <listeners>
            <listener class="\PHPUnit\TextUI\Command" file="--coverage-php=storage/coverage.php"/>
        </listeners>
    </phpunit>
    
    • Store reports in storage/coverage.php (avoid Tests/ for cleaner project structure).
  2. Add a Custom Task in composer.json:

    "scripts": {
        "test": [
            "phpunit",
            "@check-coverage"
        ],
        "check-coverage": "vendor/bin/code-coverage-checker storage/coverage.php line 95.0"
    }
    

    Run with:

    composer test
    

Advanced Patterns

1. Directory-Specific Thresholds

Enforce stricter coverage for critical paths (e.g., app/Services/):

vendor/bin/code-coverage-checker storage/coverage.php line 90.0 app/Services/
  • Only files in app/Services/ are checked against the threshold.

2. Dynamic Thresholds via Environment

Use .env or CI variables:

COVERAGE_THRESHOLD=${COVERAGE_THRESHOLD:-90.0} \
vendor/bin/code-coverage-checker storage/coverage.php line $COVERAGE_THRESHOLD

3. Symfony Integration

For Symfony projects, leverage the symfony/phpunit-bridge:

php bin/phpunit --coverage-php=var/tests/coverage.php
vendor/bin/code-coverage-checker var/tests/coverage.php method 98.0

4. Parallel Testing Compatibility

If using phpunit-parallel, generate a single merged report:

phpunit --coverage-php=storage/coverage-merged.php --coverage-clover=storage/coverage.clover
vendor/bin/clover-to-php storage/coverage.clover > storage/coverage-merged.php
vendor/bin/code-coverage-checker storage/coverage-merged.php line 90.0

Laravel-Specific Tips

  • Artisan Command: Create a custom command to wrap the checker:

    // app/Console/Commands/CheckCoverage.php
    namespace App\Console\Commands;
    
    use Illuminate\Console\Command;
    use Symfony\Component\Process\Process;
    
    class CheckCoverage extends Command
    {
        protected $signature = 'coverage:check {threshold : Coverage threshold (e.g., 90.0)}';
        protected $description = 'Check code coverage against a threshold';
    
        public function handle()
        {
            $process = new Process([
                'vendor/bin/code-coverage-checker',
                'storage/coverage.php',
                'line',
                $this->argument('threshold')
            ]);
    
            $process->run();
            if (!$process->isSuccessful()) {
                $this->error($process->getOutput());
                exit(1);
            }
            $this->info('Coverage check passed!');
        }
    }
    

    Run with:

    php artisan coverage:check 90.0
    
  • Laravel Forge/Envoyer: Add the check to deployment scripts:

    php artisan test
    php artisan coverage:check 90.0 || exit 1
    

Gotchas and Tips

Pitfalls

  1. Report Path Issues

    • Error: File not found: Tests/reports/coverage.php
    • Fix: Ensure the path is correct and the file is generated. Use --coverage-php in PHPUnit to debug:
      phpunit --coverage-php=storage/debug-coverage.php
      
    • Tip: Add a pre-check in your script:
      [ -f "storage/coverage.php" ] || (echo "Coverage report missing!" && exit 1)
      
  2. Symfony/PHPUnit-Bridge Conflicts

    • Error: Class not found: PHPUnit\TextUI\Command
    • Fix: Ensure symfony/phpunit-bridge is installed and compatible:
      composer require --dev symfony/phpunit-bridge
      
    • Tip: Use explicit versions in composer.json to avoid conflicts:
      "require-dev": {
          "symfony/phpunit-bridge": "^6.0",
          "phpunit/phpunit": "^9.5"
      }
      
  3. Threshold Granularity

    • Gotcha: Floating-point precision can cause flakiness (e.g., 90.0 vs. 90.00).
    • Fix: Use integer thresholds where possible (e.g., 90 instead of 90.0) or round in your script:
      vendor/bin/code-coverage-checker storage/coverage.php line "$(echo 90.5 | cut -d. -f1).0"
      
  4. Root Directory Reports

    • Issue: Reports for root-level files (e.g., app/) may not parse correctly.
    • Fix: Update to v0.2.5+ (includes fixes for root directory reports). If issues persist, manually exclude the root:
      vendor/bin/code-coverage-checker storage/coverage.php line 90.0 --exclude=app/
      
      (Note: --exclude is not natively supported; use directory-specific thresholds instead.)
  5. CI Cache Invalidation

    • Problem: Stale coverage reports in CI caches can cause false passes/fails.
    • Solution: Clear the report file before running:
      rm -f storage/coverage.php
      phpunit --coverage-php=storage/coverage.php
      vendor/bin/code-coverage-checker storage/coverage.php line 90.0
      

Debugging Tips

  1. Verbose Output Run the checker with -v for debug info:

    vendor/bin/code-coverage-checker -v storage/coverage.php line 90.0
    
    • Look for lines like:
      Checking file: app/Models/User.php (95.2% coverage)
      
  2. Inspect the Coverage File The coverage.php file is a PHP array. Inspect it directly:

    php -a <<< '$f = file_get_contents("storage/coverage.php"); eval("?>".file_get_contents($f)); print_r($coverage);'
    
    • Helps verify data structure if the checker fails silently.
  3. List Uncovered Files Use v0.2.9+ to list files below threshold:

    vendor/bin/code-coverage-checker storage/coverage.php line 90.0 --
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky