phpfui/phpunit-syntax-coverage
A PHPUnit extension that measures PHP syntax coverage, showing which language constructs and parser nodes your test suite actually exercises. Use it to spot untested syntax like new operators, match expressions, or traits, then close those gaps with focused tests.
Architecture fit
The package targets a real blind spot in PHPUnit's native coverage model: PHPUnit can only report on files the interpreter actually loaded during the run, so source files that are never autoloaded are silently absent from the report rather than reported as 0%. Syntax coverage closes that gap by scanning the source tree for files the test suite never caused PHP to parse. For a Laravel codebase — where service providers, console commands, queued jobs, Blade-compiled classes, and event listeners are frequently never touched by the default test path — this is a meaningful signal that line coverage alone does not produce.
Architecturally it is a dev-only PHPUnit extension: it registers via phpunit.xml, has no runtime footprint in the application, and requires no production code changes. That is the lowest-risk integration shape available to us.
Integration feasibility
High on paper. composer require --dev, one extension entry in phpunit.xml, one new CI step. No service, no daemon, no schema, no credentials. Realistically a single engineer can produce a working POC in under a day.
Technical risk
The technical risk is low; the supplier risk is high.
Key questions
php artisan test --parallel / paratest — are results aggregated correctly across workers?vendor/, generated code, migrations, and files excluded via phpunit.xml <source> directives?Stack fit
Good fit for Laravel 10–12 on PHP 8.1+, provided the PHPUnit major aligns. It complements rather than replaces coverage: line coverage tells us what executed, syntax coverage tells us what was never even reachable by the suite. The two reports should be consumed side by side, not merged into a single number.
Migration path
Greenfield-style addition — there is nothing to migrate. Treat as an additive instrumentation layer:
composer require --dev phpfui/phpunit-syntax-coveragephpunit.xml (validate against the schema version for our PHPUnit major)Compatibility
Composer will resolve PHPUnit constraints at install time; conflicts surface immediately and cheaply, which is the right failure mode. The higher-risk incompatibility is semantic — it installs cleanly but the extension never fires. Mitigate with a smoke assertion in the POC: introduce a deliberately unloaded class and confirm the tool reports it.
Sequencing
Maintenance
Near-zero steady state if it works: one composer line, one XML block, one CI job. The maintenance burden is almost entirely contingent — it materializes as a spike of work when we next bump PHPUnit majors, not as ongoing toil. Because it is dev-only, it never ships and never participates in incident response.
Support
No vendor, no SLA. GitHub issues against a one-person project. Set expectations accordingly: this is an experiment, not a procurement. If the POC shows value, designate an internal owner (one name team) responsible for PHPUnit-upgrade validation.
Scaling
Two scaling concerns.
--parallel flag forks test processes. If results are not aggregated across workers, coverage will under-report and the tool becomes noise. This is the single most likely reason the rollout stalls in a Laravel shop, and it should be the first thing the POC tests.Failure modes
Ramp-up
Trivial for consumers — the output is a report, so no new mental model beyond "files we never loaded." Engineer ramp-up is roughly half a day to install and configure, plus the POC validation. The real adoption cost is social: convincing teams that a second coverage metric is worth a CI job. Recommend framing it as dead-code and untested-path detection, not as another coverage percentage to be argued about in code review.
How can I help you explore Laravel packages today?