Get started with browser tests in Laravel

Get started with browser tests in Laravel

Motivation

Laravel is a popular PHP framework that enables the rapid development of applications. But is it essential to perform browser tests? Yes, because it ensures that the continuous deployment doesn't break anything and helps you confidently perform production deployments.

Ready to learn how to write browser tests in Laravel? Let’s begin.

Use case

Before we get into the details, we’ll consider a use case against which we will write tests. Let's assume we want to build a todo list using Laravel. A list will have to-do items.

We will write a test for the Create operation. Below is the todoitem schema design:

attributetypedescription
PKidbigintPrimary key
titlevarchar(255)Title
created_attimestamp
updated_attimestamp

We skipped the specification of models, controllers, etc., to keep it simple.

Tests

We would like to validate whether, on the form submission, the intended data is inserted into the database.

Laravel's Dusk framework is used to write the browser test.

use App\Models\TodoItem;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Laravel\Dusk\Browser;
use Tests\DuskTestCase;

class TodoItemControllerTest extends DuskTestCase
{

    /* This makes sure that the table is populated with any seeded data */
    public bool $seed = true;

    /* This makes sure that the migrations are executed before every test */
    use DatabaseMigrations;

    /**
     * Verifies that the add form is not accessible to unauthenticated
     * users.
     */
    public function testNotAccessibleToAnonymousUser(): void
    {
        $this->get('/todoitem/create')
            ->assertStatus(403);
    }

    /**
     * Verifies that the add form is actually able to insert data.
     */
    public function testCreateTodoItem(): void
    {
        // Setup.
        $user = User::factory()->create();

        // Tests.
        $this->browse(static function (Browser $browser) use ($user) {
            $browser->loginAs($user)
                ->visit('/todoitem/create')
                // This simulates that "Pick Groceries" is typed into a textfield with `item` as `name` attribute.
                // You can also use your own Dusk selector. Refer: https://laravel.com/docs/dusk#dusk-selectors.
                ->type('item', 'Pick Groceries')
                // This simulates that a button with "Add" written on it is clicked.
                ->click('Add');

            $browser->loginAs($user)
                ->visit('/todoitem/create')
                ->type('item', 'Meet Carolina')
                ->click('Add');
        });

        // Assertions.
        $this->assertDatabaseHas('todoitem', [
            'title' => 'Pick Groceries',
        ]);
        $this->assertDatabaseHas('todoitem', [
            'title' => 'Meet Carolina',
        ]);
    }
}

Run tests

To execute the browser tests, you can use the following command:

php artisan dusk

Wrapping up

I hope you found this helpful. For more details, you can refer to the Dusk documentation. It provides various helper methods to interact with a page and will help you write a more robust test.

I have used Dusk for writing the browser tests. However, you can also choose other frameworks like cypress.

To achieve continuous integration, you must execute these tests on every code push. To run the tests automatically, you can rely on tools like Jenkins, TravisCI, etc.