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.