Weave Code
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

Pest Plugin Route Testing Laravel Package

spatie/pest-plugin-route-testing

Pest plugin for Laravel that automatically tests all your app’s GET routes. Run a single test to assert responses are successful, redirects, forbidden, not found, etc. Filter routes by pattern and provide models for route model bindings via bind().

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require --dev spatie/pest-plugin-route-testing
    

    Ensure spatie/pest-plugin is also installed (this package is a plugin for Pest).

  2. First Test File: Create a test file (e.g., tests/Feature/RouteTests.php) and add:

    use function Spatie\RouteTesting\routeTesting;
    
    it('ensures all GET routes return success', function () {
        routeTesting('all GET routes')
            ->assertSuccessful();
    });
    

    Run with:

    ./vendor/bin/pest
    
  3. First Use Case: Verify all public-facing routes (e.g., /, /about, /contact) return 200. Useful for:

    • Post-deployment checks.
    • CI/CD pipelines to catch broken routes early.

Implementation Patterns

Core Workflows

  1. Testing All Routes:

    routeTesting('all routes')
        ->assertSuccessful();
    
    • Tests all routes (GET, POST, etc.) by default. Use ->get() or ->post() to filter HTTP methods.
  2. Scoped Testing:

    routeTesting('admin routes')
        ->include('admin/*')
        ->assertSuccessful();
    
    • include(): Whitelist routes (supports glob patterns like admin/* or regex).
    • exclude(): Blacklist routes (e.g., ->exclude('api/*')).
  3. HTTP Method Filtering:

    routeTesting('API endpoints')
        ->post()
        ->put()
        ->assertSuccessful();
    
    • Chain methods (get(), post(), etc.) to test specific verbs.
  4. Route Model Bindings:

    routeTesting('user profile routes')
        ->include('users/*')
        ->bind(User::factory()) // Auto-generates a fake user
        ->assertSuccessful();
    
    • bind(): Provides fake models for routes like /users/{user}.
  5. Custom Assertions:

    routeTesting('auth routes')
        ->include('login', 'register')
        ->assertRedirect();
    
    • Use Laravel’s TestResponse assertions (e.g., assertForbidden(), assertSee()).

Integration Tips

  1. Combine with Pest Plugins:

    use function Pest\Laravel\actingAs;
    use function Spatie\RouteTesting\routeTesting;
    
    it('tests authenticated routes', function () {
        actingAs(User::factory()->create());
        routeTesting('authenticated routes')
            ->include('dashboard/*')
            ->assertSuccessful();
    });
    
  2. Dynamic Route Testing:

    it('tests routes in a feature branch', function () {
        $routes = Route::getRoutes()->getRoutes();
        $newRoutes = collect($routes)->filter(fn ($route) =>
            str_contains($route->uri(), 'new-feature')
        );
    
        routeTesting('new feature routes')
            ->routes($newRoutes)
            ->assertSuccessful();
    });
    
  3. CI/CD Hooks: Add to .github/workflows/test.yml:

    - name: Test Routes
      run: ./vendor/bin/pest --filter "routeTesting"
    
  4. Local Development: Use in php artisan tinker to debug:

    \Spatie\RouteTesting\routeTesting('broken routes')
        ->exclude('health-check')
        ->dd(); // Dumps failing routes
    

Gotchas and Tips

Pitfalls

  1. Route Model Bindings:

    • Issue: Routes like /users/{user} fail if no model is bound.
    • Fix: Use ->bind(User::factory()) or exclude them with ->exclude('users/*').
  2. Middleware Conflicts:

    • Issue: Routes with auth middleware may fail if unauthenticated.
    • Fix: Mock auth or use actingAs() (Pest/Laravel plugin).
  3. Dynamic Routes:

    • Issue: Routes with optional parameters (e.g., /posts/{id?}) may not match expectations.
    • Fix: Explicitly test them or use ->include('posts/*').
  4. Performance:

    • Issue: Testing thousands of routes can be slow.
    • Fix: Scope tests (e.g., ->include('api/*')) or run in parallel with Pest’s --parallel flag.
  5. Environment-Specific Routes:

    • Issue: Routes like /admin may not exist in testing env.
    • Fix: Use ->onlyIn('local') (if supported) or mock routes in routes/web.php for testing.

Debugging Tips

  1. Inspect Failing Routes:

    routeTesting('debug routes')
        ->dd(); // Dumps all routes with metadata (URI, methods, middleware)
    
  2. Log Route Failures:

    routeTesting('log failures')
        ->assertSuccessful()
        ->fail(function (array $failedRoutes) {
            foreach ($failedRoutes as $route) {
                Log::error("Failed route: {$route['uri']} (HTTP: {$route['response']->status()})");
            }
        });
    
  3. Skip Routes Temporarily:

    routeTesting('skip maintenance routes')
        ->exclude('maintenance')
        ->assertSuccessful();
    

Extension Points

  1. Custom Assertions: Extend Spatie\RouteTesting\RouteTester to add assertions:

    namespace App\Tests\Extensions;
    
    use Spatie\RouteTesting\RouteTester;
    
    class CustomAssertions extends RouteTester
    {
        public function assertHasJsonApiError(): static
        {
            return $this->assertJsonStructure(['errors']);
        }
    }
    

    Use in tests:

    routeTesting('API errors')
        ->post()
        ->assertHasJsonApiError();
    
  2. Predefined Route Groups: Create a helper trait:

    trait RouteGroups
    {
        protected function adminRoutes(): array
        {
            return ['admin/*'];
        }
    }
    

    Use in tests:

    routeTesting('admin panel')
        ->include($this->adminRoutes())
        ->assertSuccessful();
    
  3. Hook into Pest Events:

    beforeEach(function () {
        if (app()->environment('testing')) {
            \Spatie\RouteTesting\routeTesting('pre-flight check')
                ->exclude('health-check')
                ->assertSuccessful();
        }
    });
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport