Weave 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

Phpunit Syntax Coverage Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

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.

  • Abandonment exposure. 2 stars, 0 dependents, a single maintainer. This is an unvalidated package with no ecosystem signal. The composite score of 16/100 is consistent with that read.
  • Blast radius is contained. Because it is dev-only and produces a report rather than mutating code, removal is a one-line revert. There is no lock-in, which is what makes the adoption defensible despite the maturity signal.
  • PHPUnit version coupling is the primary breakage vector. PHPUnit's extension/listener API has churned across 9 → 10 → 11 → 12. An extension built against one major silently stops running on another — and a silently unregistered extension is worse than no extension, because it yields a false sense of coverage.
  • Pest compatibility is unproven. Most current Laravel teams run Pest; Pest wraps PHPUnit but has its own plugin surface. This must be tested, not assumed.

Key questions

  1. Which PHPUnit majors are supported, and is the constraint pinned or open-ended?
  2. Minimum PHP version, and does it support 8.3/8.4?
  3. Does it require Xdebug or PCOV, or does it operate independently of the coverage driver?
  4. Is output machine-readable (Clover/JUnit/JSON) so we can gate CI, or human-readable only?
  5. How does it behave under php artisan test --parallel / paratest — are results aggregated correctly across workers?
  6. How does it handle vendor/, generated code, migrations, and files excluded via phpunit.xml <source> directives?
  7. What is the wall-clock and memory overhead on a ~2,000-file codebase?

Integration Approach

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:

  1. composer require --dev phpfui/phpunit-syntax-coverage
  2. Register in phpunit.xml (validate against the schema version for our PHPUnit major)
  3. Run report-only against an existing service; capture baseline
  4. Publish the baseline as an artifact and review, do not gate yet

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

  • Phase 1 (spike, ~2 days): POC on one mid-sized Laravel service. Validate Pest support, parallel test runner behavior, and machine-readable output. Decision gate: does it surface anything our existing coverage report misses?
  • Phase 2 (advisory): Add as a non-blocking CI job on 2–3 services. Measure overhead and noise.
  • Phase 3 (selective gating): Gate only on regressions — new files introduced with zero syntax coverage — rather than an absolute percentage threshold. Absolute thresholds on a legacy codebase generate political cost with no near-term payoff.
  • Phase 4 (exit plan): If the maintainer goes dark and a PHPUnit upgrade breaks it, either pin our PHPUnit version or vendor the MIT-licensed source in-tree and patch it ourselves. Budget roughly 2–3 engineer-days for the fork-and-patch path; the surface area is small enough that this is credible.

Operational Impact

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.

  • Compute: AST/parse-based scanning over a monorepo's source tree grows with codebase size. Benchmark at our largest service before rolling out widely; if the job exceeds a few minutes, scope it to changed packages in CI.
  • Correctness under parallelism: Laravel's --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

  • Silent no-op after PHPUnit upgrade — most dangerous; produces green CI with no data. Mitigate with a canary test that asserts the extension reports a known-uncovered file.
  • False positives on generated code — compiled Blade views, Ide Helpers, migration stubs, and factories inflate the "uncovered" list and erode trust. Requires explicit exclusion configuration.
  • Conditional/optional autoload paths — code reachable only in certain environments reads as dead. Accept and document; do not chase to zero.
  • Composer constraint conflict blocking a PHPUnit upgrade — a dev dependency holding back a core testing upgrade is a bad trade. Hard rule: if it blocks a PHPUnit major, drop the package rather than the upgrade.

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.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource