behat/phpunit-assertions-extension
Behat extension that brings PHPUnit assertions into Behat step definitions, letting you use assertSame, assertTrue, and other familiar assertions in scenarios for clearer, more expressive test failures.
Architecture fit. This is a thin Behat extension whose only job is to register PHPUnit's assertion library so that step definitions can call assertSame(), assertTrue(), etc. instead of Behat's own PHPUnit\Framework\Assert-style web assertions. It does not touch application code, HTTP, or the database, and it carries no runtime footprint in production. Architecturally it is a developer-experience shim, not infrastructure — which is good, because it means blast radius is confined to the test suite.
The fit problem is contextual, not technical. Laravel's default testing stack is PHPUnit (or Pest on top of it), and Pest's expect() API already provides readable assertions with first-class Laravel integration. Behat is a BDD/Gherkin runner that appears in Laravel estates almost exclusively as legacy carry-over from a Symfony or agency-template origin. So the package only has a home in the narrow intersection of "we run Behat" and "we have not already solved assertions in step definitions."
Integration feasibility. Mechanically trivial: composer require --dev behat/phpunit-assertions-extension, add the extension class to behat.yml, done. No service provider, no config publishing, no migrations, no facade. Realistic effort is under an hour for a single suite, including a smoke test that an assertion actually fires inside a step.
Technical risk. This is where the package fails evaluation, and the metadata is unambiguous:
Key questions to resolve before any decision:
composer.json constraints, not the README.Stack fit. Poor for a greenfield Laravel or Pest codebase, and I would not introduce it there. It is defensible only where Behat already exists and step definitions are currently doing hand-rolled if (...) { throw new \Exception(...) } checks — the extension replaces bespoke assertion plumbing with a standard library. Even then, the equivalent one-line alternative is a base FeatureContext that uses PHPUnit\Framework\Assert or exposes an assert() helper — roughly 30 lines of code we own outright, with no third-party dependency and no version-skew exposure.
Migration path. Two viable paths, and I would recommend the second:
require-dev, register the extension in behat.yml, migrate step definitions incrementally per feature file, keep a rollback branch.PHPUnit\Framework\Assert directly. Same developer ergonomics, zero dependency risk, identical exit cost (none). This is the recommendation unless the package is verified to wrap something non-obvious.Compatibility. If adopted, pin the extension, Behat, and PHPUnit together in composer.json, and add a CI job that runs the Behat suite — not just PHPUnit — so a PHPUnit bump fails loudly rather than silently degrading assertion behaviour. Explicitly exclude the extension from automated dependency-bump bots until compatibility is confirmed per major.
Sequencing.
composer why behat/behat and inventory how many step definitions need assertions.Maintenance. Effectively self-maintained. With 0 dependents and an explicit "not for new projects" warning, assume no upstream fixes for a PHPUnit 12/13 incompatibility. Budget for either a fork or an in-house replacement within the planning horizon; both are cheap only if adoption is small.
Support. None beyond GitHub issues. No vendor, no CVE process, no backport policy. This is acceptable for a dev-only assertion helper and unacceptable for anything touching CI gating — and this does touch CI gating, because a broken bridge can turn failing scenarios green.
Scaling. Trivial. The extension loads once per Behat run and has no bearing on production throughput, memory, or infrastructure. The scaling concern is organisational: every additional Behat suite deepens the dependency, and every additional Laravel app in the estate that inherits the tooling inherits the risk.
Failure modes.
Error/TypeError inside steps, producing confusing failures that teams misattribute to application bugs.composer.json lags and eventually pins the whole application's PHP upgrade path.Ramp-up. Near-zero to use, which is precisely the trap — engineers will adopt it in an afternoon without appreciating that they have added an unmaintained chokepoint to CI. The genuine ramp-up cost is Behat/Gherkin fluency itself, which the extension does nothing to address.
Recommendation. Do not adopt. The package solves a real but small ergonomics problem, and the cost of solving it ourselves is a short trait or base context that we own, test, and can change on our own schedule. If a team is already running this extension, leave it in place but treat it as frozen: no new step definitions should rely on it, and the next PHPUnit major upgrade is the natural trigger to replace it with the in-house equivalent.
How can I help you explore Laravel packages today?