We’ve released a new package called spatie/pest-plugin-route-testing. This package can test all common routes in your Laravel app by writing a single test.

In this blog post, I’d like to tell you all about it.

Why this package was created

When people start out writing tests for their Laravel apps, I usually give the advice to test your home page. The homepage usually is a very simple URL to test; it’s just a simple GET request. Here’s a video that explains how to test the homepage taken from our Testing Laravel course. Here’s how such a test could like:

it(‘can render the homepage‘, function() {
$this
->get(‘/‘)
->assertSuccessful();
});

Now, in real-world applications, there are typically more simple pages like the homepage, where you could write a simple test to make sure that it works. When adding simple pages to your application, it’s easy to forget to write a test for them.

That’s why we created our new spatie/pest-plugin-route-testing package. It allows you to write a single test to make sure all simple GET requests like pages in your app work.

Using spatie/pest-plugin-route-testing

use function SpatieRouteTestingrouteTesting;

routeTesting(‘all GET routes‘)->assertSuccessful();

This will test all GET routes in your application and ensure they return a 200 HTTP status code. Here’s what the output looks like when you run this test in a small app.

Instead of assertSuccessful(), you can use any assertion that is available in Laravel’s TestResponse class, such as assertRedirect(), assertNotFound(), assertForbidden(), etc.

You can also test specific routes:

use function SpatieRouteTestingrouteTesting;

routeTesting(‘all blog routes‘)
->include(‘blog*‘)
->assertSuccessful();

If there are routes that have route model bindings, the package will skip the test for those routes. Let’s assume you have a route defined as user/{user}. Here’s what the output looks like when you run the test.

If you want to test a route with a route model binding, you can provide the model using the bind method.

use function SpatieRouteTestingrouteTesting;
use AppModelsUser;

routeTesting(‘all blog routes‘)
->bind(‘user‘, User::factory()->create())
->assertSuccessful();

When you run the test now, the package will use the provided model to test the route.

If you want to exclude routes from the test, you can use the exclude method. Here’s an example that tests all routes except the ones that start with admin.

use function SpatieRouteTestingrouteTesting;

routeTesting(‘all blog routes‘)
->exclude(‘admin*‘)
->assertSuccessful();

You can use the setUp method to execute code before the route test is run. Here’s an example where we log in a user before running the test.

use function SpatieRouteTestingrouteTesting;

routeTesting(‘all admin routes‘)
->setUp(function ()
{
$user = User::factory()->create();

$this->actingAs($user);

// optionally, you could also bind the model
$this->bind(‘user‘, $user);
})
->include(‘admin*‘)
->assertSuccessful();

In closing

Using spatie/pest-plugin-route-testing, it’s easy to test all simple pages of your Laravel app. New pages will automatically be tested too.

My colleague Niels came up with the original idea for this package, and Alex did a big refactor on the internals.

This isn’t the first package our team has created. You can see everything we do in open-source on the open-source pages on our company website.

Categories: PHP