phpunit/phpunit-story
phpunit/phpunit-story brings behavior-driven development to PHPUnit, letting you write given/when/then story scenarios as test cases. A small, legacy extension useful for BDD-style specs, though now largely superseded by modern tooling.
Architecture fit. phpunit/phpunit-story is a dev-only PHPUnit extension that adds a Given/When/Then "story" runner on top of PHPUnit's test suite machinery. It does not touch application architecture, service boundaries, or runtime behavior — it is confined to require-dev and CI. That is the good news. The bad news is that its extension points are the pre-namespacing PHPUnit internals (PHPUnit_Framework_TestSuite, PHPUnit_Extensions_*), which were removed when PHPUnit adopted namespaces in 6.0. Against a modern Laravel baseline (PHP 8.1+, PHPUnit 10/11, Pest 2/3), the architecture fit is effectively zero: it cannot be loaded, let alone executed, without a legacy PHPUnit runtime.
Integration feasibility. Low. Composer resolution alone is likely to block adoption — the package pins phpunit/phpunit to the 3.7/4.x line, which directly conflicts with the PHPUnit constraint of any Laravel release from 5.5 onward. Isolating it in a sidecar container is theoretically possible but creates a second, divergent test runtime that no one will maintain. For a package with 36 stars, an archived status, and an unrecognized repository, there is no upstream to file issues against and no release cadence to plan around.
Technical risk. High across the board:
NOASSERTION means automated license detection failed. Legal/OSS review must treat this as unknown until provenance is established; that alone can block a commercial codebase.Key questions for the decision gate. (1) Which existing suites, if any, actually contain story-style specs — and what business behavior do they protect? (2) Is the intent BDD syntax or BDD collaboration? Only the former would ever justify a runner. (3) Can legal confirm a license, or is the provenance unrecoverable? (4) Is there a maintained fork, or does the team accept a rewrite regardless? (5) Who owns dev-tooling lifecycle budget, and are they willing to own a dead dependency?
Recommendation: do not adopt. The package's value proposition (Gherkin-ish specs inside PHPUnit) is fully covered today by Behat, Codeception, or Pest's higher-order expectations, all of which are maintained and PHP 8-ready.
Stack fit. None for a current Laravel stack. It is only plausible in a legacy Laravel 4.x/5.0-era application still pinned to PHP 5.6/PHPUnit 4 and not yet on the upgrade path — and even there it is a liability, not an asset.
Migration path. Treat this as an exit, not an entry.
*Story, *Scenario, Given/When/Then blocks) and map each to the behavior it asserts.PHPUnit_Extensions_Story_* references remain.Compatibility. Requires PHP ~5.3–7.0 and PHPUnit <5. The blocking constraint is not Laravel itself but the PHPUnit version, which is transitively locked by the framework's orchestra/testbench/phpunit constraints. There is no shim, bridge, or compatibility layer available, and no upstream to publish one.
Sequencing. (a) Discovery and spec inventory — 1 sprint, low cost, informs everything else. (b) Decision gate with legal and engineering — confirm license status and the actual need for BDD syntax. (c) If, and only if, exact legacy behavior must be preserved, run an isolated PoC in a php:5.6 container to characterize behavior before rewriting. (d) Rewrite in Behat/Pest behind the existing CI gate so coverage is provably non-decreasing. (e) Remove the dependency and add a lock-file lint to prevent reintroduction.
Maintenance. Zero upstream maintenance. Any fix — PHP version bump, PHPUnit API change, security patch — becomes internal work with no reference implementation. Budget for a rewrite rather than for upkeep.
Support. No vendor, no maintainer, no issue tracker reachable, no CVE process. Internal support burden falls entirely on the platform/QA owner. The NOASSERTION license adds review overhead on every dependency audit, and will resurface each time the OSS policy is re-run.
Scaling. The runner models each story as its own suite, which inflates bootstrap and reporting overhead on large suites and offers no known compatibility with parallel execution (paratest, Pest parallel). It also produces a second, non-standard output format, complicating CI result ingestion, flaky-test tracking, and coverage aggregation.
Failure modes.
--ignore-platform-reqs or pin transitive versions, degrading the whole dependency graph.Ramp-up. Deceptively shallow — the Given/When/Then DSL looks familiar, so engineers assume fluency, but the dialect is a PHPUnit-specific variant with sparse documentation and no community examples. Realistic ramp-up is "read the source of an archived package," which is exactly the cost the team is trying to avoid by using a test framework in the first place. Net: adoption raises onboarding cost while lowering the floor on maintainability.
Bottom line for the roadmap: this is a documented dead end, not a candidate. Capture the intent (readable, behavior-oriented specs) as a quality initiative, deliver it with a maintained tool, and close the dependency question permanently.
How can I help you explore Laravel packages today?