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

Autotest Bundle Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

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:

  1. composer require --dev mano/autotest-bundle
  2. Register the bundle in config/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.
  3. Look at, in this order: the 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).
  4. First use case: a single CI job that boots the kernel, walks the router's 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.

Implementation Patterns

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.

Gotchas and Tips

  • v1.1.2 is a breaking change shipped as a patch. "Alter resolver interface to return route decorator" changes a public-ish contract on a 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.
  • The release is a signal, not a rescue. After a long dormancy post-February 2022, there's one commit touching an internal interface — no Laravel support, no README growth, no Symfony 6.3+/7 constraint widening mentioned. Don't read activity as maintenance. Score/dependents remain negligible: vendor a fork you control if this is critical CI.
  • Check constraints before you plan around it. The dormancy means 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.
  • 302 is not a failure, and 404 probably isn't either. Redirects to login and missing-entity responses are normal in a bare environment. Assert < 500, not == 200, or your first run will be a wall of false positives.
  • Only GET routes get exercised in the default flow. POST/PUT/DELETE routes are silently untested — don't mistake a green run for full coverage.
  • State leaks between routes. If the run shares a database and one route writes, a later route may behave differently. Run against a freshly migrated DB, or wrap each request in a transaction if you extend the runner.
  • Rate limiting and CSRF middleware will produce 429/419s that look like failures. Disable both in the test env.
  • Debugging a failure: the failing route is usually obvious from the exception, but the cause is often a container compile error masked by a generic 500 — and after an interface change like 1.1.2's, "decorator returned the wrong type" will look identical to "app is broken." Reproduce by hitting the same URI with curl against a freshly booted dev server before blaming the bundle.
  • Extension points are thin but slightly less thin than before. You get config-based exclusions plus the resolver/decorator pair from 1.1.2 (custom assertions, per-route headers, fixture hooks). Anything still requires touching the runner — which, given the maintenance status, you were probably going to do anyway. Read the handful of source files before extending; it's an afternoon.
  • Don't install it in a Laravel app "to try it." It will sit inert in vendor/ and cost you ten minutes of confusion. Read the source on GitHub instead.
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.
abbasudo/artisan-route
mirvan/ippanel
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
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package