This website uses cookies

Our website, platform and/or any sub domains use cookies to understand how you use our services, and to improve both your experience and our marketing relevance.

Introduction to Laravel Dusk: Testing Todo App

Published on April 6, 2017 - Content Updated on

7 Min Read
Testing-Todo-App

In the previous part of this series, I completed the ToDo app. Today, I am going to test this app using Laravel Dusk. I will start this article with a brief introduction of Laravel Dusk, how you can set up Laravel Dusk and then go into the process of testing the ToDo application.

What is Laravel Dusk?

Laravel Dusk gives an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK or Selenium on your local computer. Instead, Dusk uses a standalone ChromeDriver development..

Dusk is a Laravel package that performs end-to-end (E2E) tests on Laravel applications. Giving client-side testing by running tests in a browser, Dusk permits engineers to see client-side features tested in real time, mirroring how a client would utilize them

Install Laravel Dusk

Laravel Dusk can be installed by running the following command:

composer require laravel/dusk

Once the installation finishes, I will register it inside the `register()` method in `AppServiceProvider`. For this, go to app/Providers folder and open AppServiceProvider.php file. Add the following line right before the start of the class:

use Laravel\Dusk\DuskServiceProvider;

Next, in the `register()` method, paste the following code:

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

At this point, `AppServiceProvider` class will look like this:

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use Laravel\Dusk\DuskServiceProvider;
class AppServiceProvider extends ServiceProvider
{
    /**
* Bootstrap any application services.
*
* @return void
*/
    public function boot()
    {
        //
        Schema::defaultStringLength(191);
    }
    /**
* Register any application services.
*
* @return void
*/
    public function register()
    {
        if ($this->app->environment('local', 'testing')) {
            $this->app->register(DuskServiceProvider::class);
        }
    }
}

Now, run the following command to install Laravel Dusk:

php artisan dusk:install

Once the command is completed, the Browser directory will be created inside the tests directory (this will contain an Example Test file). In this directory, I will create all the tests for browser automation.

Next, I will describe the testing process of the ToDo app.

You might also like: Automate Code Testing With PHP Continuous Integration

Creating Browser Test Cases for the ToDo App

I will use the default browser (Chrome) for the tests.

First of all, run the following command to create a new Test file:

php artisan dusk:make TodoTest

Once the command finishes, it will create a new test file with the name TodoTest inside the Browser directory. This file will contain an example test case method `testExample()`. Remove this method from the file.

Before I start adding the methods for test cases, open .env file and add the full app URL in the  APP_URL constant.

APP_URL=http://localhost/todoapplaravel/public

Now, I could start writing the test cases.

User Registration Test

I will begin by creating a new test function which will test user registration process and check whether the user is redirected to the dashboard.

Inside the `TodoTest` class, create a new function with the name `testRegister()`. Paste the following code in it:

public function testRegister()
{
    $this->browse(function ($browser) {
        $browser->visit('register')
            ->type('name', 'Tayor Otwell')
            ->type('email', '[email protected]')
            ->type('password', 'ahmedkhan')
            ->type('password_confirmation', 'ahmedkhan')
            ->attach('userimage', 'C:\images\taylor.jpg')
            ->press('Register')
            ->assertPathIs('/todoapplaravel/public/todo');
    });
}

In the above code, I called the `browse` method along with the `$browser` instance, which is automatically passed by Dusk and used to make assertion for the application. First, I used the `visit()` method to direct the browser to the register page. Then, in the `type` method, I first defined the name of the input field and after the comma, I assigned its value. Since I am using a file input type in the registration form, I have used the `attach` method to attach the file to the input. I entered the name of the type file input field and then defined the path where the image is saved at the local machine. Next, I used `press` (used to press the button on the web page). Inside this, I defined the button to press (in this case, it is Register). Finally, I checked the assert that the user is redirected to the dashboard i.e. ‘/todo/’ by using the `assertPathIs` method. I need to add the full URL, as shown in the browser after the ‘localhost’, i.e. ‘/todoapplaravel/public/todo’.

Create a New ToDo Test

Now, create a new method with the name `testCreateTodo()`. Add the following code in it.

public function testCreateTodo()
{
    $this->browse(function ($browser) {
        $browser->visit('todo')
            ->clickLink('Add Todo')
            ->type('todo', 'Testing it With Dusk')
            ->type('category', 'dusk')
            ->type('description', 'This is created with dusk')
            ->press('Add')
            ->assertPathIs('/todoapplaravel/public/todo');
    });
}

After redirecting to the ‘todo’, I have used the `clickLink` method to click on the add todo, since it is a link, not a button. Next, I added todo input values. Once done, I pressed the Add button. Next, I am asserting that it is redirected to the dashboard. The todo item has been added successfully. If not, then assert would fail.

View the Todo Test

Before creating this test, I need to edit the dashboard.php file. I will add an id to all the icons so that I can click them using the automation testing. For this, go to the resources/views/todo directory and open the dashboard.php file. Now, replace the code in this file with the following:

@extends('layouts.app')
@section('title', 'Home ')
@section('content')
 <div class="row">
      <div class="col-md-9">
    <ul class="list-group">
    @if($todos != false)
          @foreach ($todos as $todo)

    <li class="list-group-item"><a id="view{{$todo->id}}" class="secondary-content" href="{{url('/todo/'.$todo->id)}}"><span class="glyphicon glyphicon-triangle-right"></span></a><a id="edit{{$todo->id}}" class="secondary-content" href="{{url('/todo/'.$todo->id).'/edit'}}"><span class="glyphicon glyphicon-pencil"></span></a><a id="delete{{$todo->id}}" href="#" class="secondary-content" onclick="event.preventDefault();
                                            document.getElementById('delete-form').submit();"><span class="glyphicon glyphicon-trash"></span></a><form id="delete-form" action="{{url('/todo/'.$todo->id)}}" method="POST" style="display: none;">
                         {{ method_field('DELETE') }}{{ csrf_field() }}
                            </form> {{$todo->todo}} 
                                            </li>

@endforeach
@else
<li class="list-group-item"> No Todo added yet <a href="{{ url('/todo/create') }}"> click here</a> to add new todo. </li>
@endif
    </ul>
    </div>

      <div class="col-md-3">
          <img class="img-responsive img-circle" src="{{asset('storage/'.$image)}}">
      </div>
    </div>
@endsection

In the above code, I gave an id to the view,edit & delete. This is a  concatenation of the view and the id of a todo i.e. `id=”view{{$todo->id}}”` for view, `id=”edit{{$todo->id}}”` for edit and `id=”delete{{$todo->id}}”` for delete.

Now, I will create the todo test for viewing todo. For this, go to the TodoTest.php file and add a new method `testViewTodo()` with the following code:

public function testViewTodo()
{
    $this->browse(function ($browser) {
        $browser->visit('todo')
            ->assertVisible('#view1')
            ->visit(
            $browser->attribute('#view1', 'href')
        )
            ->assertPathIs('/todoapplaravel/public/todo/1')
            ->clickLink('Edit')
            ->type('description', 'Testing it with dusk again')
            ->press('Update')
            ->assertPathIs('/todoapplaravel/public/todo/1');
    });
}

In the above code, I first visited ‘todo’ and then asserted that id #view1 exists in the dashboard. Then, I visited this link using the `visit` method. Inside this method, I defined which attribute to click using the `attribute` method. Next, I asserted its path. If it is valid, I called the clickLink method to click on the Edit link, which is visible on that page. Next, I have edited its description using the `type` method and then pressed the Update button using the press method. Next, I  checked the path again to see that it redirect back to the same todo or not using `assertPathis` method.

Stop Wasting Time on Servers

Cloudways handle server management for you so you can focus on creating great apps and keeping your clients happy.

Edit the Todo Test

Now, create a new function with name the `testEditTodo`. Add the following code to it:

public function testEditTodo()
{
    $this->browse(function ($browser) {
        $browser->visit('todo')
            ->assertVisible('#edit1')
            ->visit(
            $browser->attribute('#edit1', 'href')
        )
            ->type('description', 'Testing it with dusk again')
            ->press('Update')
            ->assertPathIs('/todoapplaravel/public/todo/1');
    });
}

In The above code, I first redirected to the dashboard and then clicked the edit icon, updated the todo description and then asserted that the path is same or not.

Delete a Todo Test

Now, create a new function with the name `testDeleteTodo`. Add the following code to it:

public function testDeleteTodo()
{
    $this->browse(function ($browser) {
        $browser->visit('todo')
            ->assertVisible('#delete1')
            ->visit(
            $browser->attribute('#delete1', 'href')
        )
            ->assertPathIs('/todoapplaravel/public/todo');
    });
}

Logout Test

Now, create a new function with the name `testLogout()` and add the following code to it:

public function testLogout()
{
    $this->browse(function ($browser) {
        $browser->visit('todo')
            ->clickLink('Logout')
            ->assertPathIs('/todoapplaravel/public/login');
    });
}

After registration, the user is automatically redirected to Login page. That’s why, I have not created the login test before. Now, create a new function with the name `testLogin` and paste the following code in it:

public function testLogin()
{
    $this->browse(function ($browser) {
        $browser->visit('login')
            ->type('email', '[email protected]')
            ->type('password', 'ahmedkhan')
            ->press('Login')
            ->assertPathIs('/todoapplaravel/public/todo');
    });
}

At this point, all the test cases for the ToDo app have been created. The complete TodoTest file will look like the following:

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;

use Illuminate\Foundation\Testing\DatabaseMigrations;

class TodoTest extends DuskTestCase

{

    /**

    * Register test.

    *

    * @return void

    */

   public function testRegister()

   {

       $this->browse(function ($browser) {

           $browser->visit('register')

                   ->type('name', 'Tayor Otwell')

                   ->type('email', '[email protected]')

                   ->type('password', 'ahmedkhan')

                   ->type('password_confirmation', 'ahmedkhan')

                   ->attach('userimage', 'C:\Users\ahmed.khan\Downloads\CreatingToDoApplicationinLaravel5.4CreatingAuthToDoViewsRoutesandModifyingController\images\taylor.jpg')

                   ->press('Register')

                   ->assertPathIs('/todoapplaravel/public/todo');

       });

   }

  /**

    * Create Todo test.

    *

    * @return void

    */

   public function testCreateTodo()

   {

       $this->browse(function ($browser) {

           $browser->visit('todo')

                   ->clickLink('Add Todo')

                   ->type('todo', 'Testing it With Dusk')

                   ->type('category', 'dusk')

                   ->type('description', 'This is created with dusk')

                   ->press('Add')

                   ->assertPathIs('/todoapplaravel/public/todo');

       });

   }

   /**

    * View and Edit Todo Test.

    *

    * @return void

    */

   public function testViewTodo()

   {

       $this->browse(function ($browser) {

           $browser->visit('todo')

                   ->assertVisible('#view1')

                   ->visit(

                       $browser->attribute('#view1', 'href')

                   )

                   ->assertPathIs('/todoapplaravel/public/todo/1')

                   ->clickLink('Edit')

                   ->type('description', 'Testing it with dusk again')

                   ->press('Update')

                   ->assertPathIs('/todoapplaravel/public/todo/1');

       });

   }

   /**

    * Edit todo test.

    *

    * @return void

    */

   public function testEditTodo()

   {

       $this->browse(function ($browser) {

           $browser->visit('todo')

                   ->assertVisible('#edit1')

                   ->visit(

                       $browser->attribute('#edit1', 'href')

                   )

                   ->type('description', 'Testing it with dusk again')

                   ->press('Update')

                   ->assertPathIs('/todoapplaravel/public/todo/1');

       });

   }

   /**

    * Delete Todo test.

    *

    * @return void

    */

   public function testDeleteTodo()

   {

       $this->browse(function ($browser) {

           $browser->visit('todo')

                   ->assertVisible('#delete1')

                   ->visit(

                       $browser->attribute('#delete1', 'href')

                   )

                   ->assertPathIs('/todoapplaravel/public/todo');

       });

   }

   /*

    * Logout test.

    *

    * @return void

    */

   public function testLogout()

   {

       $this->browse(function ($browser) {

           $browser->visit('todo')

                   ->clickLink('Logout')

                   ->assertPathIs('/todoapplaravel/public/login');

       });

   }

   /**

    * Login test.

    *

    * @return void

    */

   public function testLogin()

   {

       $this->browse(function ($browser) {

           $browser->visit('login')

                   ->type('email', '[email protected]')

                   ->type('password', 'ahmedkhan')

                   ->press('Login')

                   ->assertPathIs('/todoapplaravel/public/todo');

       });

   }

}

 

This test case file has been added to the todo app Laravel repo on the GitHub.

One Command To Test Them All

On the command line, run the following command to run the automation tests:

php artisan dusk

Check out the following GIF to see browser testing with Laravel Dusk in action:

Laravel Dusk

Concluding The Series

This series focuses on the Laravel powered ToDo application, starting off with setting up migration tables, controller and models. Then, creating user authentication, views and setup ToDo functionality. In the final part of the series, I carried out browser testing of Laravel applications using Laravel Dusk.

Share your opinion in the comment section. COMMENT NOW

Share This Article

Customer Review at

“Cloudways hosting has one of the best customer service and hosting speed”

Sanjit C [Website Developer]

Ahmed Khan

Ahmed was a PHP community expert at Cloudways - A Managed PHP Hosting Cloud Platform. He is a software engineer with extensive knowledge in PHP and SEO. He loves watching Game of Thrones is his free time. Follow Ahmed on Twitter to stay updated with his works. You can email him at [email protected]

×

Get Our Newsletter
Be the first to get the latest updates and tutorials.

Thankyou for Subscribing Us!

×

Webinar: How to Get 100% Scores on Core Web Vitals

Join Joe Williams & Aleksandar Savkovic on 29th of March, 2021.

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!

Do you like what you read?

Get the Latest Updates

Share Your Feedback

Please insert Content

Thank you for your feedback!