mano/autotest-bundle
Mano AutoTest Bundle is a PHP package for simplifying automated testing workflows. It helps generate, organize, and run tests with minimal setup, making it easier to add consistent coverage to your project and catch regressions earlier.
Read this first: despite the name, this is a Symfony bundle, not a Laravel package. There is no service provider, no config/autotest.php, and Composer will happily install it into a Laravel app without anything happening. As a Laravel developer your realistic options are (a) use it on a Symfony service you happen to maintain, or (b) steal the idea, which is the more valuable one.
If you are on the Symfony side:
composer require --dev mano/autotest-bundleconfig/bundles.php (dev/test envs only) — required, there is no auto-discovery in Symfony Flex for third-party bundles unless the recipe exists, and with a handful of stars it almost certainly doesn't.DependencyInjection/Configuration.php (what you can actually configure), the console command class (what it does when it runs), the route resolver + decorator classes (v1.1.2's new seam — see Gotchas), and the repo's own tests/ directory (the only real documentation).RouteCollection, and asserts no GET route returns a 5xx.That last sentence is the whole package. It's a smoke test, not a functional test framework. Set expectations accordingly.
CI smoke gate (the intended use). Run the bundle's command after migrations and fixtures in your pipeline, before the real test suite. Treat any 500 as a build failure. It catches the class of bug that unit tests miss: a broken service definition, a missing env var, a Twig template that references a deleted variable. Cheap and high signal.
Route exclusion is the main configuration surface. Every app has routes that are un-runnable in a bare test environment — payment webhooks, OAuth callbacks, routes hitting an external API. Find the exclusion/allowlist option in the bundle config and maintain it deliberately; an exclusion list that grows every sprint is a sign the smoke test is decaying.
Auth and parameters. Most real routes need a logged-in user and a bound entity. The bundle can't infer those. In practice you either exclude authenticated routes wholesale or seed a test user and set a session cookie before the run. Parameterised routes (/orders/{id}) need real IDs in the database — seed deterministic fixtures and pin the IDs.
Custom resolution, post-1.1.2. The resolver interface now returns a route decorator rather than (presumably) a plain route/response. In practice this is where you'd inject per-route behaviour — headers, auth, a bound {id} — without forking the command. If you maintain a Symfony service and need anything beyond config exclusions, implement the resolver and register the decorator in services YAML. It's still a small seam, but it's now a documented-ish one.
Porting to Laravel (the recommended path). php artisan route:list --json gives you the same enumeration the bundle gets from Symfony's router. A Pest dataset makes a 30-line smoke suite:
dataset('get-routes', function () {
return collect(json_decode(Artisan::call('route:list', ['--json' => true]) ? Artisan::output() : '[]', true))
->filter(fn ($r) => in_array('GET', $r['method']))
->reject(fn ($r) => str_contains($r['uri'], '{')) // start by skipping parameterised routes
->map(fn ($r) => '/' . ltrim($r['uri'], '/'))
->all();
});
it('does not 500', function (string $uri) {
$this->get($uri)->assertStatus(fn ($s) => $s < 500);
})->with('get-routes');
Grow it by adding actingAs() for authenticated groups and per-route datasets for parameterised ones. This is the bundle's value proposition, restated in a framework you can actually debug.
Integration tip: wire it into the same job as phpstan/php-cs-fixer rather than the unit test job. Smoke tests are environment-sensitive; running them in a container that mirrors staging is where they earn their keep.
1.1.x release. If you had implemented the resolver interface against 1.1.1, your class will now fatal on composer update. Pin the version (1.1.1 or 1.1.2, deliberately) and diff the resolver/decorator signatures before upgrading.composer.json may still pin symfony/framework-bundle and PHP versions from the 5.x era. Be prepared to fork and widen them regardless of what 1.1.2 changed.< 500, not == 200, or your first run will be a wall of false positives.POST/PUT/DELETE routes are silently untested — don't mistake a green run for full coverage.curl against a freshly booted dev server before blaming the bundle.vendor/ and cost you ten minutes of confusion. Read the source on GitHub instead.How can I help you explore Laravel packages today?