handcraftedinthealps/code-coverage-checker
A small CLI tool for PHPUnit that reads a --coverage-php report and fails when line, class, or method coverage falls below a threshold you set. Limit checks to specific directories if needed, making it easy to gate CI builds on real coverage numbers.
Architecture fit.
The package is a dev-only CLI that consumes a PHPUnit --coverage-php report and exits non-zero when coverage is below a threshold. It is not a Laravel package: no service provider, config, runtime hooks, or application coupling. That makes it architecturally safe to trial and easy to remove. For Laravel teams, the fit is strongest where PHPUnit is already the test runner and CI needs a simple quality gate. It supports line/class/method metrics and optional directory scoping, which maps well to module-level quality policies. However, Laravel already provides native coverage minimum enforcement via php artisan test --coverage --min=90 in modern versions, so this package’s incremental value is mainly per-directory thresholds, metric choice, and a failing-file list. It does not replace coverage generation, dashboards, or historical trend tracking.
Integration feasibility.
High, with caveats. Add it as a require-dev dependency, generate a PHP coverage report in CI with vendor/bin/phpunit --coverage-php coverage.php, then run vendor/bin/code-coverage-checker coverage.php line 90 app/. This fits GitHub Actions, GitLab CI, and Laravel Forge deploy scripts. Laravel’s php artisan test wrapper may not expose --coverage-php, so teams may need to invoke PHPUnit directly for this report. CI must have Xdebug or PCOV available. A spike should validate PHPUnit version compatibility, report path handling, and exit-code behavior before rollout.
Technical risk.
Implementation risk is low; adoption risk is high. The tool is small and MIT-licensed, so forking or replacing it is feasible. But 6 stars and 0 dependents indicate little production validation. Compatibility is the main unknown: release notes show PHPUnit 9 and Symfony 6–8 support, but PHPUnit 10/11 and newer Laravel upgrades may change coverage report formats. Root-directory and file-report edge cases were fixed in v0.2.5, but monorepo behavior is not proven. Static thresholds can block urgent releases unless an override process exists. Coverage generation also adds CI time.
Key questions.
Should we use Laravel’s native --coverage --min instead, and add this package only for per-directory or class/method policies? Which modules get thresholds, and who approves exceptions? What PHPUnit/PHP version matrix must be supported? Who owns upgrades and a possible fork if the package is abandoned? How will failures be surfaced: CI log, Slack, merge-request comment? Do we need historical trend tracking, which this tool does not provide? Is the failing-file output sufficient for developers to act quickly?
Stack fit.
Good for Laravel projects on PHP 8+ with PHPUnit as the test runner. It is a Composer dev dependency and CI step, not an application dependency. It complements rather than replaces SonarQube, CodeClimate, or Coveralls. If the team uses Pest, check whether Pest’s built-in --min covers the need; use this package only if per-directory enforcement is required. If Laravel’s native --min is sufficient, do not add another dependency.
Migration path.
Phase 1: spike in one CI pipeline with a permissive threshold, such as 70%, to confirm report generation and exit codes. Phase 2: add a Composer script such as coverage:check and document local usage. Phase 3: enforce in CI as a required check, then tighten thresholds and add per-directory rules for critical modules. No database, runtime, or service migration is involved. Pin the dependency in composer.lock and treat upgrades as controlled changes.
Compatibility.
Verify against the project’s Laravel, PHP, and PHPUnit versions before rollout. The package targets PHP 8+, PHPUnit 9+, and Symfony 6–8; older Laravel/PHP 7.x stacks need validation or should not adopt. Ensure CI has Xdebug or PCOV. Confirm the generated coverage.php path and include/exclude rules match phpunit.xml. Test PHPUnit major upgrades in a branch because coverage report formats can change.
Sequencing.
handcraftedinthealps/code-coverage-checker as require-dev and pin the version.coverage.php.composer coverage:check script.--min or a small internal script.Maintenance.
Low code footprint but low community support. Assign an owner to monitor releases and PHPUnit/Laravel compatibility. Because the package is small and MIT-licensed, the fallback is to fork or vendor a minimal checker. Budget a few hours per year for upgrades and CI verification; more if PHPUnit majors change.
Support.
No commercial support. Rely on GitHub issues, README, and internal documentation. Developer support burden is low: one CLI command with clear failure output listing non-compliant files. The TPM should ensure a runbook covers missing coverage drivers, report path errors, and threshold exceptions.
Scaling.
Scales with CI because there is no server component. Large coverage reports may add seconds to CI; restrict checks to critical directories and cache or artifact reports where possible. For monorepos, run per-package checks or split CI jobs. It does not provide dashboards or trend history; pair with a coverage service if leadership needs reporting over time.
Failure modes.
Missing Xdebug/PCOV means no report and a failed check. PHPUnit major upgrades can break report parsing. Overly strict thresholds can block hotfixes; define an override label and approval path. CI timeouts can occur if coverage generation is slow. Low adoption means unknown edge cases; pilot on a representative Laravel app first. Confirm that the checker’s non-zero exit code actually fails the pipeline.
Ramp-up.
Very low for engineers familiar with PHPUnit: one command locally, one CI step to understand. Allocate about 30 minutes per engineer for onboarding and 1–2 hours for CI setup. The harder work is policy: choosing thresholds, exclusions, exception handling, and whether Laravel’s native --min makes this package unnecessary. The TPM should frame adoption as a quality-gate policy decision, not just a tooling choice.
How can I help you explore Laravel packages today?