phpunit/php-code-coverage
phpunit/php-code-coverage collects, processes, and renders PHP code coverage data. Use it to start/stop coverage during tests, filter included files, and generate reports such as OpenClover XML from live runs or serialized coverage data.
CodeCoverage into test listeners).composer require with no Laravel-specific setup.--coverage flag via custom test listeners.extend() or before/after hooks.| Risk Area | Mitigation Strategy |
|---|---|
| PHP Version Compatibility | Laravel 10+ uses PHP 8.2–8.3; package drops PHP 8.3 support in v13.0.0. Upgrade to v12.x for full compatibility. |
| Xdebug/PCOV Conflicts | Package handles conflicts (e.g., #1131), but test locally with both drivers. |
| Performance Overhead | XML report generation is optimized (v12.5.x+), but parallel test runs may still hit race conditions (fixed in v13.0.2). |
| Breaking Changes | v14.0.0 removed Report\PHP; migrate to Serialization\Serializer. |
| Dark Mode/HTML Reports | v12.4.0+ supports dark mode, but custom CSS may override styles. |
Artisan::call()).--parallel)?--coverage with a custom listener using php-code-coverage.extend() to inject coverage collection.Artisan::call() or HandleCommands for CLI coverage.before/after hooks in HandleQueues to start/stop coverage.OpenClover format (experimental in v12.3.0+).Storage or Vite.| Step | Action | Tools/Libraries |
|---|---|---|
| 1. Add Dependency | composer require --dev phpunit/php-code-coverage |
Composer |
| 2. Configure PHPUnit | Replace --coverage with a custom listener (see example below). |
PHPUnit |
| 3. Filter Scope | Define Filter to exclude vendor/, node_modules/, etc. |
SebastianBergmann\CodeCoverage\Filter |
| 4. Generate Reports | Use ReportFacade for OpenClover/HTML in post-test hooks. |
Report\Facade |
| 5. CI/CD Integration | Serialize coverage (Serializer) and upload to SonarQube/GitHub. |
GitHub Actions, SonarScanner |
| 6. Optimize | Enable caching (CacheWarmer) for large codebases. |
SebastianBergmann\CodeCoverage\Cache |
Example: PHPUnit Listener
use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Driver\Selector;
use SebastianBergmann\CodeCoverage\Filter;
use SebastianBergmann\CodeCoverage\Report\Facade as ReportFacade;
class CoverageListener implements \PHPUnit\Runner\Listener
{
public function startTestSuite(\PHPUnit\Framework\TestSuite $suite): void
{
$filter = (new Filter)->includeFiles([__DIR__.'/../src/*']);
$coverage = new CodeCoverage((new Selector)->forLineCoverage($filter), $filter);
$coverage->start('laravel-tests');
}
public function endTestSuite(\PHPUnit\Framework\TestSuite $suite): void
{
$coverage->stop();
ReportFacade::fromObject($coverage)->renderOpenClover(storage_path('app/coverage.xml'));
}
}
CodeCoverage as a singleton for reuse across tests.laravel/pint, spatie/laravel-test-factory, etc.--coverage with custom listener.^12.5 for PHP 8.2 compatibility (Laravel 10).^14.0 for new features (e.g., dark mode), but test thoroughly.app/ → src/).Filter (e.g., ./src/*).Filter::includeUncoveredFiles() to debug missed files.How can I help you explore Laravel packages today?