pierstoval/smoke-testing
Quickly smoke-test your PHP application by crawling configured URLs and checking responses for errors. Catch broken pages, unexpected status codes, and regressions early with simple setup and clear results, making it easy to verify deployments before users do.
Reality check first: this is a Symfony bundle. There is no service provider, no config/smoke_testing.php, and it will not boot in a Laravel app. Treat this assessment as "what a Symfony team gets from it, and what a Laravel dev can steal from the idea" — the transferable part is the pattern (route-discovery smoke tests + a link crawler), not the code.
Minimal Symfony setup:
composer require --dev pierstoval/smoke-testing
Register the bundle only in the test env in config/bundles.php:
Pierstoval\SmokeTesting\PierstovalSmokeTestingBundle::class => ['test' => true],
Add config/packages/test/smoke_testing.yaml with the smallest thing that works:
smoke_testing:
base_url: '%env(SMOKE_TEST_BASE_URL)%'
excluded_paths:
- '/_profiler'
- '/login'
Then boot your app (symfony serve, php -S, or your Docker stack) and run the crawl command — check bin/console list smoke-testing for the exact name in your version (smoke-testing:run in recent releases). The command crawls from the base URL, follows internal links, and reports non-2xx/3xx responses.
Where to look first:
DependencyInjection/Configuration.php — it is the authoritative list of options; the README drifts between versions.bin/console config:dump-reference smoke_testing after install — faster than reading docs.FunctionalTest base class (see below) — this is the half of the package most teams actually keep long-term.First real use case: point it at a seeded, running app right after a framework/dependency upgrade. It catches the "500 on a page nobody manually visits" class of regressions in one command, with zero test code written.
The package gives you two distinct mechanisms; most teams should pick one as primary.
1. The crawler command (breadth-first, HTTP-level).
doctrine:fixtures:load, then the crawl, then assert exit code.excluded_paths aggressively. Everything behind auth, payment, admin, or destructive GETs should be excluded from the crawl and covered separately.2. Generated functional tests (per-route, kernel-level — no running server).
base_url, and shows per-route failures in JUnit output./orders/{id} gets something that exists in fixtures.Auth patterns.
$client->loginUser($user) in a setUp — far more stable than replaying a form submission.Layering with existing tests.
tests/Smoke) so a 500 on /legal/terms doesn't obscure your unit-suite failures.APP_ENV=test or a dedicated smoke env, separate database, MAILER_DSN=null://, MESSENGER_TRANSPORT_DSN=in-memory:// (or sync), and the web debug toolbar off. The toolbar injects HTML and can break content assertions; a real mailer will spam people during a crawl./login, which then looks like a dead page. Either log in first or exclude the whole authenticated prefix — don't "fix" it by loosening the success-status check./orders/{id} with no default silently fails the smoke test. Provide parameter defaults or exclude the route; the functional-test side has attributes for exactly this.base_url must be reachable from the process running the command. Docker networking bites here: localhost inside a container is the container, not your host. Use the service name.'/admin' vs '^/admin' behave differently; over-broad patterns silently exclude most of your site and you get a green build that tests nothing. Sanity-check the crawl log's visited-URL count.var/log/test.log before assuming the bundle is wrong.php artisan route:list → an HTTP test per route, plus spatie/crawler for the link-walking half. The value proposition here is genuinely small (39 stars, low traction) — read it as a pattern reference, not a dependency.How can I help you explore Laravel packages today?