Hace unas horas se ha publicado la versión Alpha de Laravel Dusk. Dusk es un nuevo componente para realizar pruebas automatizadas en Laravel que nos permitirá probar aplicaciones desde la perspectiva de un usuario, incluso aquellas que hagan uso de JavaScript en el navegador.

A grandes rasgos, es una capa de abstracción sobre el Webdriver creado por Facebook, al que se han agregado métodos para poder hacer pruebas sobre Laravel de forma más sencilla. Por defecto utiliza Chromedriver, un driver para que las pruebas se ejecuten sobre Chrome, pero es posible usar otros navegadores soportados por Selenium.

Ten en cuenta que es una versión Alpha, por lo que puede contener errores, o puede que la API se modifique en el futuro. La documentación del componente aún no está disponible, pero podrás ver ya algunos ejemplos en el repositorio de GitHub https://github.com/laravel/dusk

Instalación

Laravel Dusk sólo está disponible actualmente para Mac y Linux, pronto estará disponible también para Windows.

Para probar Dusk vamos a crear un nuevo proyecto con la versión 5.4 de Laravel. Como esta versión aún está en desarrollo, debemos indicar a Composer que nos instale la versión de desarrollo:

composer create-project laravel/laravel probando-dusk dev-develop

Si tienes el instalador de Laravel puedes usar laravel new probando-dusk –dev (no olvides colocar –dev para instalar la versión en desarrollo).

A continuación, entramos a la carpeta del proyecto e instalamos el componente de Dusk:

cd probando-dusk
composer require laravel/dusk

En el método `register` de `AppServiceProvider` nos aseguramos que se registre el Service Provider de Dusk:

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

El Servide Provider está añadido aquí, en lugar del array de providers de la configuración, para poder limitar los entornos en los que Dusk se ejecuta, ya que Dusk agrega una funcionalidad para poder iniciar sesión como otros usuarios para facilitar los tests. Por seguridad, lo debemos limitar únicamente a los entornos de testing.

Ahora vamos a ejecutar el siguiente comando:

php artisan dusk:install

Este comando generará en el directorio tests  el fichero DuskTestCase.php , que contendrá la clase de la que extenderán las pruebas de Dusk, y el directorio Browser , donde podremos crear todas nuestras pruebas.

Por último, debes configurar la aplicación para que sea accesible desde una url, y debes configurar esa url en el fichero .env . En mi caso, configuré un virtualhost con la siguiente url:

APP_URL=http://probando-dusk.dev

Con esto ya podemos comenzar a ejecutar las pruebas. Para ejecutar los tests, usamos el comando:

 php artisan dusk

Si todo ha ido bien, la terminal deberá mostrar un mensaje indicando que el test de ejemplo ha pasado correctamente:

En mi caso tuve problemas, ya que los tests no comenzaban y al final fallaban por timeout. Si te ocurre lo mismo, para solventar el problema de forma temporal y poder probar Dusk puedes descargar Chromedriver y ejecutarlo de forma manual en una terminal aparte, indicándole un puerto diferente al que Laravel configura por defecto.

wget https://chromedriver.storage.googleapis.com/2.27/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
./chromedriver --port=9123

En mi caso descargué la versión para Linux de 64 bits. Descarga la versión correspondiente para tu sistema operativo en https://sites.google.com/a/chromium.org/chromedriver/downloads

Y por último, en el archivo DuskTestCase.php  modifica la URL del WebDriver para indicar el puerto configurado anteriormente:

    protected function driver()
    {
        return RemoteWebDriver::create(
            'http://localhost:9123', DesiredCapabilities::chrome()
        );
    }

Ahora ya puedes probar de nuevo a ejecutar los tests:

 php artisan dusk

Ten en cuenta que Dusk abrirá un navegador para ejecutar las pruebas. Por lo tanto, es posible que no funcione si lo ejecutas en un servidor. Al probar Dusk he comprobado que no funciona en Homestead, así que las pruebas las he ejecutado en mi propio equipo.

Creando nuestra primera prueba con Dusk

Vamos a crear una prueba que compruebe que un usuario se carga correctamente con JavaScript. Para hacer el ejemplo sencillo, no vamos a guardar el usuario en la base de datos, sino que simplemente devolveremos un array con sus datos.

Para crear la prueba puedes usar el comando php artisan dusk:make NombreDelTest:

php artisan dusk:make UserTest

Esto creará un nuevo test en tests/Browser/UserTest.php . En el test incluiremos el siguiente código:

<?php

namespace Tests\Browser;

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

class UserTest extends DuskTestCase
{
    function test_can_see_user_profile()
    {
        $this->browse(function ($browser) {
            $browser->visit('/profile')
                ->waitFor('#user')
                ->assertSeeIn('.name', 'abalozz')
                ->assertSeeIn('.email', '[email protected]');
        });
    }
}

En el test estamos indicando los siguientes pasos:

  • Abre un nuevo navegador.
  • Visita la url /profile.
  • Espera a que se cree un elemento con el id #user  en la página.
  • Comprueba que en un elemento con la clase .name  se muestra el nombre.
  • Comprueba que en un elemento con la clase .email  se muestra el email.

Podemos ejecutar esta prueba prueba de forma individual con

 php artisan dusk --filter test_can_see_user_profile

o ejecutar todas con

php artisan dusk

Dusk utiliza PHPUnit, por lo que podemos pasarle los mismos argumentos que usamos con PHPUnit.

Al ejecutar la prueba nos mostrará un mensaje similar a este:

There was 1 error:

1) Tests\Browser\UserTest::test_can_see_user_profile
Facebook\WebDriver\Exception\TimeOutException: Waited 5 seconds for callback.

Este error, aunque no queda muy claro, quiere decir que estuvo esperando 5 segundos a que se mostrase el elemento #user en la página, pero no ocurrió. Además puedes ver la captura de pantalla del error en la carpeta tests/Browser/screenshots/

Para solucionar esto vamos a crear la página y dicho elemento. Añade en routes/web.php  las rutas necesarias.

Route::get('/profile', function () {
    return view('profile');
});

Route::get('/users/1', function () {
    return [
        'id' => 1,
        'name' => 'abalozz',
        'email' => '[email protected]',
    ];
});

Y crea la vista resources/views/profile.blade.php  con el siguiente contenido:

<div id="app"></div>

<script type="text/javascript">
    fetch('/users/1').then(function (response) {
        return response.json();
    }).then(function (user) {
        document.querySelector('#app').innerHTML = `
            <div id="user">
                <p class="name">${user.name}</p>
                <p class="email">${user.email}</p>
            </div>
        `;
    });
</script>

El código anterior requiere de ES6 así que asegúrate de tener instalada la última versión de Chrome para poder ejecutarlo sin problemas.

Si ejecutas ahora la prueba, debe pasar correctamente:

$ php artisan dusk --filter test_can_see_user_profile
PHPUnit 5.7.5 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 1.02 seconds, Memory: 10.00MB

OK (1 test, 2 assertions)

Fíjate que la vista carga los datos del usuario de forma dinámica usando JavaScript y que Dusk está validando correctamente que los datos del usuario se han agregado a la página.

Ventajas de Dusk frente a otros sistemas de testing

Las versiones anteriores de Laravel ya incluyen un sistema que permiten hacer pruebas simulando ser un usuario, el Browser Kit Testing el cuál se ha explicado de forma extensa en el curso Crea una aplicación con Laravel 5.3 y TDD. Sin embargo, ese componente no ejecuta JavaScript, por lo cuál sólo resulta útil para partes de nuestra aplicación donde no se requiera de JavaScript.

También existen otros sistemas que sí permiten probar aplicaciones hechas con JavaScript (CodeceptJS, Nightmare.js, Protractor, entre otros), sin embargo estos sistemas no están integrados con Laravel, además de que los tests debemos programarlos con JavaScript.

Laravel Dusk permite escribir las pruebas directamente en PHP, lo que nos permite aprovechar funcionalidades del framework como los Model Factories. Además, integra algunos métodos que nos ayudan a probar las aplicaciones, como el método loginAs, con el que podemos simular que un usuario ha iniciado sesión de forma sencilla.

Más adelante en Styde habrán más tutoriales y lecciones sobre cómo sacarle el máximo provecho a Laravel Dusk.

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.