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

Placeholder Phpunit Laravel Package

php-extended/placeholder-phpunit

A placeholder package for PHPUnit in php-extended projects. It provides minimal stubs so libraries can reference PHPUnit types without a hard dependency, keeping production installs lean while remaining compatible when PHPUnit is present.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What the package actually is. php-extended/placeholder-phpunit is a Composer-installable stub of PHPUnit's public API surface (interfaces, and likely the abstract classes such as PHPUnit\Framework\TestCase and Constraint despite the "interfaces only" description). Its purpose is to let a library declare a runtime type dependency on PHPUnit symbols without pulling phpunit/phpunit and its dependency tree into production installs. It ships no test runner, no assertions implementation, and no behaviour — only type declarations.

Architecture fit. Low for a Laravel application, narrow-but-legitimate for a distributed Laravel/PHP library. The only scenario where this earns its place is a package whose public API exposes PHPUnit types — custom constraints, custom assertions, base test-case classes, data-provider helpers, PHPUnit extensions — and which does not want to force every consumer to install PHPUnit. In a typical Laravel app this is a non-problem: PHPUnit already lives in require-dev, and nothing in app/ should reference PHPUnit\* at all. A TPM should treat this as a library-authoring tool, not an application dependency.

Integration feasibility. Mechanically trivial — one composer require line, no service provider, no config, no runtime footprint. The feasibility risk is almost entirely about provenance and version alignment, not effort. The repository is a GitLab-hosted, single-maintainer project inside the sprawling php-extended namespace, with zero stars and zero dependents. That is effectively zero production evidence: no downstream usage to learn failure modes from, no issue history to read, no compatibility matrix.

Technical risk.

  • API drift is the dominant risk. PHPUnit's public surface changes materially across majors: TestListener removed in PHPUnit 10, TestCase signatures and expectException* behaviour evolved, metadata moved from annotations to attributes, Constraint internals shifted. A placeholder must be re-cut for every PHPUnit major, and a stale stub produces TypeError/fatal signature-mismatch errors rather than clean failures — frequently in consumer projects, not in this repo's CI. Laravel 11/12 sit on PHPUnit 10/11/12; a placeholder pinned to PHPUnit 7/8-era interfaces is worse than useless.
  • Autoload ambiguity. In a dev install both this package and phpunit/phpunit are present, both mapping the same fully-qualified class names. Composer's PSR-4 resolution picks whichever directory it searches first; nothing declares a conflict. The result usually "works" but makes the effective definition of TestCase/Constraint depend on autoload ordering — a genuinely nasty, non-obvious debugging class.
  • Contract incompleteness. A stub that declares only signatures will satisfy instanceof and static analysis but will fail any code that calls a concrete method on those types, or that mocks/extends them expecting real behaviour. Teams routinely misread "interfaces exist" as "PHPUnit works."
  • Supply-chain exposure. Unaudited, unpinned third-party code entering require (production) rather than require-dev enlarges the blast radius for a package that adds no product value.

Key questions to resolve before any adoption.

  1. Is the package published on Packagist, and under what version tags? If it requires a VCS repository entry, that alone likely disqualifies it.
  2. Which PHPUnit major versions does the stub mirror today, and what is the maintainer's stated cadence for following PHPUnit releases?
  3. Does it declare conflict with phpunit/phpunit, or is coexistence undefined?
  4. Does it include abstract classes and traits, or strictly interfaces?
  5. Are PHP and Composer constraints declared, and is there any licence/security review on file?
  6. Which of our own packages actually expose PHPUnit types in their public API? (Expect the answer to be "none" or "one".)

Integration Approach

Stack fit. Poor-to-conditional. Laravel's own conventions push PHPUnit to require-dev, and Laravel's testing story is now dual-track (PHPUnit or Pest), which makes hard-coding PHPUnit type contracts in a shipped package less attractive than it was. If a package must expose PHPUnit extension points, the idiomatic alternatives are: keep phpunit/phpunit in require-dev and accept that extension points are only exercised in test contexts; or define your own thin, version-stable interfaces and adapt to PHPUnit internally. Both avoid the stub entirely.

Migration path (if adopted at all). Restrict it to the require section of a single library — never to an application skeleton. Keep phpunit/phpunit in that library's require-dev and in the consuming app's require-dev. Add an explicit conflict or a CI assertion that only one provider of PHPUnit\ symbols is on the autoload path. Pin the placeholder to an exact version, not a range, and treat PHPUnit major upgrades as a paired-upgrade event.

Compatibility. Validate against the PHPUnit major actually in use across the estate (10/11/12 for current Laravel), not against a single app. Check PHP version constraints against Laravel's minimum (8.2+ for Laravel 11/12). Confirm Pest coexistence — Pest layers on PHPUnit, so a stub that shadows PHPUnit classes is especially hazardous in Pest projects.

Sequencing. (1) Audit internal packages for PHPUnit symbols in public signatures — likely a short list or empty. (2) Verify Packagist availability, tags, and PHPUnit-version alignment. (3) Timebox a half-day spike: install placeholder + real PHPUnit in one sandbox, dump get_class/ReflectionClass::getFileName() for TestCase and Constraint to see which provider wins, and run the suite. (4) If it passes, canary in one low-traffic library release. (5) Otherwise, document the decision as "rejected — use require-dev" so it is not re-litigated.

Recommendation. Do not adopt. With zero stars, zero dependents, a score of 0, and an unverified maintenance cadence against a moving PHPUnit API, the package's expected benefit (avoiding a dev dependency in production) is smaller than its tail risk (opaque autoload collisions and signature drift surfacing in downstream consumers). The opportunity score of 36.3 is consistent with a niche idea that is real but already better served by standard Composer practice.

Operational Impact

Maintenance. Effectively self-maintenance. The placeholder has no community to absorb PHPUnit's churn, so your team inherits the obligation to fork or patch it on every PHPUnit major (roughly annual) and on any signature change in between. Budget a recurring few hours per PHPUnit upgrade plus unplanned triage whenever a consumer reports a class-shape error.

Support. No vendor, no SLA, no security policy, single maintainer on GitLab. Internal support will fall to whoever added the dependency; that person becomes the de facto owner. Incidents will arrive as confusing downstream bug reports rather than as alerts on this package.

Scaling. Runtime cost is negligible — interface declarations only, no execution path, no memory or latency contribution. The scaling cost is organisational: each additional PHPUnit major in the supported matrix multiplies release-management work, and the risk surface grows with every package that adopts it, because autoload-ordering behaviour is global and hard to reason about per-package.

Failure modes to instrument for.

  • Fatal TypeError or "declaration must be compatible" errors in a consumer's test suite after a routine composer update.
  • Silent divergence: tests passing locally but failing in CI (or vice versa) because autoload precedence differs between a full dev install and a --no-dev production install.
  • "Class not found" in production when a non-test code path touches a PHPUnit type the placeholder did not stub.
  • Mock/prophecy failures when a stubbed abstract class lacks the concrete behaviour the test assumed.
  • Composer resolution conflicts when a package bumps PHPUnit while the placeholder stays pinned.

Ramp-up. Conceptually cheap to learn — it is a Composer autoloading and PHPUnit-extension-points problem, not a framework problem — but correctly reasoning about it requires someone comfortable with PSR-4 resolution order, composer why, and PHPUnit's versioned API. Estimate half a day to evaluate, one engineer-day to fork-and-own if pursued, and an ongoing cognitive tax on every PHPUnit upgrade. For a package that solves one narrow packaging problem, that is a poor ratio; the honest recommendation is to decline and standardise on require-dev PHPUnit plus, where genuinely needed, project-owned interfaces.

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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle