orchestra/pest-plugin-testbench
Pest Plugin for Testbench lets you use PestPHP to test your Laravel packages, bringing Pest's expressive, readable syntax to Orchestra Testbench so building and maintaining package test suites takes less boilerplate.
Architecture fit
This package is an adapter, not a platform. It registers Orchestra Testbench's package-testing harness — host application bootstrapping, service provider discovery, container swaps, database isolation, HTTP assertions — inside Pest's plugin lifecycle, so Pest spec files can consume Testbench traits without PHPUnit-style test case classes. For a TPM, the significance is that it adds no production runtime surface and no new test semantics; it reconciles two tools the team most likely already owns. That keeps the blast radius of adoption small.
Fit is high conditionally, against two preconditions:
pestphp/pest-plugin-laravel's job.Integration feasibility
Mechanically near-trivial: one require-dev entry, a uses(...) binding in pest.php, and existing Testbench-based suites continue to run under the Pest binary. The schedule cost is not wiring — it is the conversion inventory: identifying PHPUnit-annotation tests (@test, inherited setUp()/tearDown() chains, data providers) and deciding convert-versus-keep. Crucially, both runners coexist in one repository, so this is a phased migration rather than a flag day. No repo goes dark for a sprint. That single fact is what makes the initiative plannable at all.
Technical risk
The dominant risk is bus factor, not code quality. Zero dependents and a low star count normally read as abandonment, but the package lives under the orchestral organization — the same maintainers as Testbench — which materially de-risks that signal. The release history corroborates active stewardship: Pest v3 → v4 → v5 tracked across v3.0.0 / v4.0.0 / v5.0.0, Testbench v10 in v3.2.0, Laravel v13 in v4.1.0, PHP 8.4 in v3.1.0, and WithFixtures support in both v2.2.0 and v3.3.0. Prompt upstream-major tracking is precisely the maintenance tax being outsourced.
Risks the TPM must own:
RefreshDatabase semantics diverging), tests may pass while asserting against leaked or uninitialized state. That converts a tooling change into a quality-signal failure, materially worse than a failed migration.Key questions
Stack fit
This belongs in the dev-tooling layer, adjacent to pestphp/pest, pestphp/pest-plugin-laravel, orchestra/testbench, and orchestra/sidekick (a dependency from v2.1.1 / v3.2.1 onward). It fits repositories that already write feature tests against a bootstrapped Laravel application and want Pest's expressive syntax without surrendering Testbench's package-oriented bootstrap. It is a poor fit for pure unit codebases with no container dependency, and a non-fit where policy mandates PHPUnit as sole runner — in which case stop here.
Migration path
Sequence as a phased conversion, not a cutover:
pest.php, convert one small test file. Confirm the runner boots Testbench correctly and that trait behavior is genuinely applied — assert on an observable that only exists if the trait ran.Compatibility
Pin the three-way combination (Pest, Pest Plugin Laravel, this plugin) explicitly and record the supported matrix in the repo. Treat the plugin's major version as bound to Pest's major — the release notes make that relationship unambiguous. Verify Testbench alignment separately: WithFixtures support is only meaningful on Testbench versions that actually expose it.
Sequencing
Wire the tooling before any conversion work; convert before touching CI. Out of scope and must be stated as such: parallelization strategy, CI report formats, and Dusk-style browser testing. A plan that assumes this package solves those will slip. If Pest's output format breaks an existing CI reporter, discover that during the pilot, not at cutover.
Maintenance
Ongoing cost is one line in composer.json plus participation in the upstream version matrix. The honest value proposition is not velocity — it is reduced toolchain divergence and one fewer bespoke integration for the team to own. Without this package, the alternative is hand-maintaining Pest ↔ Testbench bootstrap glue: a handful of uses() bindings and base-case wiring that quietly rots on every Pest or Testbench major. Assign a named owner for the version matrix; unowned, it drifts.
Support
No vendor, no SLA, no support contract. Community coverage for this specific adapter is thin — zero dependents and a low star count signal limited Stack Overflow and blog material, not poor quality. Support therefore comes from Pest's and Testbench's own docs and source. Budget for the possibility of forking; the surface area is small, so a fork is a managed fallback rather than a crisis. MIT license keeps that option open.
Scaling
Scales linearly with the number of package repositories: each adds one dev dependency and one pest.php binding. There is no shared infrastructure to operate and no service to run. The constraint is organizational, not technical — each converted repo needs its version matrix kept aligned with the others. Past a handful of packages, standardize the binding and version constraints in a shared CI template so alignment is enforced rather than remembered.
Failure modes
orchestral org's stewardship record, but document the fork path anyway.Ramp-up
Low for engineers already writing Pest; moderate for PHPUnit-native teams, since both the syntax and the annotation-to-function conversion are new. The absence of package-specific documentation raises ramp cost — plan for one engineer to become the internal reference and write a short internal README covering the binding pattern and version matrix. A two-week pilot on one internal package, with success criteria and a rollback path agreed before it starts, is the right-sized commitment. The ask to leadership is permission to run the pilot, not a budget line.
How can I help you explore Laravel packages today?