Tutorial

Introduction to Laravel Dusk

Draft updated on Invalid Date
Default avatar

By Caleb Oki

Introduction to Laravel Dusk

This tutorial is out of date and no longer maintained.

Introduction

Laravel Dusk was one of the new features introduced in Laravel 5.4. Dusk is a tool for application testing.

One of the challenges of testing with PHPUnit was the inability to test JavaScript-based application functionality.

With Dusk the test is run in the browser so client-side features like JavaScript are testable.

Dusk is based on the open-source tools ChromeDriver and Facebook Php-webdriver which make it simple to use without the need to experience the intense procedure of setting up Selenium. In this article, we will cover installing Dusk in a Laravel application and running a few basic tests including authentication testing.

Why Dusk?

Prior versions of Laravel used Symfony BrowserKit component to simulate a web browser. This had its limitations as this is not a real browser. With Dusk the automation comes natively through its use of ChromeDriver and Facebook Php-webdriver.

One of Dusk’s features also includes the ability to wait for a condition to be true at the frontend, before executing tests. For example, it could wait for a JavaScript component or CSS selector to load before taking any action.

Installation

To begin, create a new Laravel project:

  1. laravel new dusk

Then go into the directory and pull in the laravel/dusk package

  1. cd dusk
  2. composer require laravel/dusk

When installing a Laravel package the service provider class is usually registered in the config\app.php file. However Dusk exposes some security holes that you don’t want to have in the production environment, for example, the ability to log in as other users.

To get around this, you should register the service provider class in a conditional that makes sure we are in a local environment in the app\Providers\AppServiceProvider.php file.

use Laravel\Dusk\DuskServiceProvider;// Importing DuskServiceProvider class

...

public function register()
{
    if ($this->app->environment('local', 'testing')) {
        $this->app->register(DuskServiceProvider::class);
    }
}

Next run the artisan command to install Dusk:

  1. php artisan dusk:install

This command creates a Browser directory inside the tests folder of your project and adds a basic example test. Also amongst other sub-folders, you would notice a folder named screenshots, when a test fails Dusk takes a picture of the screen and saves it in this folder. This can be useful when debugging.

Next, you need to update the APP_URL key of your .env file, with the URL you use to access your application. For example, if you are using PHP’s built-in development server to serve your application the value of App_URL could be http://localhost:8000. Make sure your development server is turned on before running a test otherwise you would have a failed test. For PHP’s built-in server run php artisan serve.

You also have the option of letting Dusk use its own environment file, to do this create a .env.dusk.{environment} file. For example, in a local environment this file would be .env.dusk.local This is useful when you do not want to test on your current database but you want to run a test off a test database.

Running Tests

To run your tests use the command:

  1. php artisan dusk

This will run the ExampleTest in tests\Browser\ExampleTest.php. You should see something like this:

This shows the test was passed and the result: OK (1 test, 1 assertion) was displayed. If you open the tests\Browser\ExampleTest.php file you would see the following method:

...
public function testBasicExample()
    {
  //Visit the homepage and look for the text 'Laravel'
        $this->browse(function (Browser $browser) {
            $browser->visit('/')
                    ->assertSee('Laravel');
        });
    }

Here the browse method accepts a callback which is an instance of the Browser class. Inside this callback you can call different methods and assertion unique to Dusk. The visit() method as its name implies is a test that visits the URL corresponding to the argument provided. The assertSee() method checks if the text corresponding to the argument given is on the page.

So in the above example, the homepage is visited and a check is made for the text ‘Laravel’. There are several assertions available, see the documentation for more information.

What happens if we replace the ‘Laravel’ text in the argument of the assertSee() method with a text that is not on the visited page? Obviously, you would get a failed test. You will see something like this:

Here the test has failed because Dusk could not find the text ‘Bla’ in the homepage to which I have changed the argument in the assertSee() method. Also, take a look at your tests\Browser\screenshots directory you should see a screenshot of the just failed test. You should see this:

Forms and Authentication

With Dusk you can also interact with forms and test authentication. To demonstrate this let’s set up Laravel’s basic login and registration forms. First, create a database and update your .env file with the database information. Then run:

  1. php artisan make:auth

This command creates scaffolding and migration files for authentication. Note that If you are running MariaDB or MYSQL version lower than 5.7.7 you need to edit the app\Providers\AppServiceProvider.php file setting the default string length in the boot method:

use Illuminate\Support\Facades\Schema;

public function boot()
{
    Schema::defaultStringLength(191);
}

Next run:

  1. php artisan migrate

This command generates our database tables from the migration files. If you go to the homepage of your project you should see the following with the Login and Register links at the far right corner:

Next, create a new test named RegisterTest test by running

php artisan dusk:make RegisterTest

Now in your tests\Browserfolder you will see the file RegisterTest.php which look like this:

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class RegisterTest extends DuskTestCase
{
    /**
     * A Dusk test example.
     *
     * @return void
     */
    public function testExample()
    {
        $this->browse(function ($browser) {
            $browser->visit('/')
                    ->assertSee('Laravel');
        });
    }
}

Edit the testExample() method to look like this

public function testExample()
    {
        $this->browse(function ($browser) {
            $browser->visit('/') //Go to the homepage
                    ->clickLink('Register') //Click the Register link
                    ->assertSee('Register') //Make sure the phrase in the arguement is on the page
      //Fill the form with these values
                    ->value('#name', 'Joe')
                    ->value('#email', 'joe@example.com')
                    ->value('#password', '123456')
                    ->value('#password-confirm', '123456')
                    ->click('button[type="submit"]') //Click the submit button on the page
                    ->assertPathIs('/home') //Make sure you are in the home page
      //Make sure you see the phrase in the arguement
                    ->assertSee("You are logged in!");
        });
    }

You may also choose to delete the ExampleTest.php file as it is no longer required. Now run

  1. php artisan dusk

You should see this:

Conclusion

Laravel Dusk makes it a lot easier and efficient to write tests. To recap we have covered the basic setup of Dusk, introduced how to write tests, and wrote an authentication test. This by no means exhausts all its features, there is still a lot more to write about. In a later article, we would delve into more of its features. If you have any questions or comments do not hesitate to post them below.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Caleb Oki

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel