vstelmakh/covelyzer
Covelyzer analyzes PHP code coverage reports and enforces per-class and per-method thresholds, failing CI builds when coverage drops below configured limits. It offers a clear console summary and flexible rules for teams tracking test quality.
Installation
composer require --dev vstelmakh/covelyzer
Add to composer.json under require-dev if not using Composer globally.
First Run Generate a Clover coverage report from PHPUnit:
./vendor/bin/phpunit --coverage-clover coverage.clover
Then analyze it with Covelyzer:
./vendor/bin/covelyzer coverage.clover
Basic Configuration
Create a covelyzer.php config file in your project root (or use defaults):
return [
'threshold' => 80, // Default coverage threshold (0-100)
'exclude' => [
'tests/',
'vendor/',
],
'format' => 'text', // Options: 'text', 'json', 'xml'
];
Analyze test coverage for a single class:
./vendor/bin/covelyzer --class=UserTest coverage.clover
Check if coverage meets your team’s threshold (e.g., 80%) and identify untested methods.
CI/CD Pipeline Add Covelyzer to your CI (e.g., GitHub Actions) to fail builds if coverage drops:
- name: Check coverage
run: ./vendor/bin/covelyzer coverage.clover --fail-on-threshold
Pre-Commit Hook
Use with tools like husky or pre-commit to enforce coverage locally:
./vendor/bin/covelyzer coverage.clover --threshold=90
Custom Reports Generate JSON/XML for programmatic use:
./vendor/bin/covelyzer --format=json coverage.clover > coverage.json
Parse in PHP:
$report = json_decode(file_get_contents('coverage.json'), true);
$lowCoverageClasses = array_filter($report['classes'], fn($c) => $c['coverage'] < 80);
'exclude' => ['tests/Unit/', 'tests/Feature/Integration/'],
./vendor/bin/covelyzer --file=src/Models/User.php coverage.clover
--previous=previous.clover to compare with a baseline report.Clover Format Dependency
phpunit --coverage-clover=coverage.clover
--coverage-clover to your PHPUnit config or .phpunit.xml.Threshold Misconfiguration
80. If set too high (e.g., 99), legitimate edge cases may fail.70 for new projects, then incrementally raise it.Exclusion Overkill
src/) may hide critical gaps.--verbose to debug excluded files:
./vendor/bin/covelyzer --verbose coverage.clover
Performance on Large Codebases
--parallel (if supported) or split reports by module.0 even if coverage fails. Use --fail-on-threshold in CI to enforce it.__construct() may show 0% coverage. Exclude them explicitly:
'exclude_methods' => ['__construct', 'staticMethod'],
Custom Rules
Extend the analyzer by subclassing Covelyzer\Analyzer and overriding analyze():
class CustomAnalyzer extends \Covelyzer\Analyzer {
protected function analyze($report) {
// Add logic (e.g., check for uncovered private methods)
}
}
Register in covelyzer.php:
'analyzer' => \App\CustomAnalyzer::class,
Output Plugins
Add custom output formats by implementing Covelyzer\Output\OutputInterface:
class SlackOutput implements OutputInterface {
public function output($data) {
// Send to Slack API
}
}
Bind in config:
'output' => \App\SlackOutput::class,
Integration with PHPStan Combine with PHPStan’s coverage rules for stricter analysis:
./vendor/bin/phpstan analyse --level=max --coverage --coverage-sources=src
./vendor/bin/covelyzer coverage.clover
How can I help you explore Laravel packages today?