Tu primer test de aceptación con Codeception
Los tests de aceptación o ‘end-to-end’ son solo la punta del diseño guiado por pruebas, pero adquieren una importancia muy grande en aplicaciones ‘legacy’.
Este tipo de tests prueban ‘casi’ como si fuéramos nosotros los que estamos interactuando como ‘personas’ o ‘actores’ con nuestro software.
Estamos de acuerdo con que son las pruebas unitarias y de integración (en menor medida) las que deben ocupar nuestro tiempo, esfuerzo y cariño.
Pero, ¿qué ocurre cuando nuestra aplicación nunca ha estado sometida a tests automatizados?
De ningún tipo. Solo hemos hecho pruebas manuales. Cada vez que lanzamos un cambio de versión repetimos una serie de procesos ‘a manita’ para ver si todo esta correcto y nada se rompe.
Estarás de acuerdo conmigo en que las cosas se complican mucho si esa aplicación que queremos mejorar es de alto valor para el negocio.
Así que empecemos por algún sitio.
Lo contamos ya con detalle en el episodio 18 y 19 de Web Reactiva Premium. Suscríbete para disfrutar de todo ese contenido.
Codeception al rescate ¶
Codeception es una librería de testing (de todos los niveles, no solo aceptación) con mucha veteranía y basada en PHP.
Tiene una versión para JavaScript llamada CodeceptJS.
Nos centraremos en generar nuestros tests desde un proyecto que solo hará eso: lanzar las pruebas E2E (end-to-end) desde allí hacia nuestro servidor local o de staging.
Instalando Codeception ¶
Seguimos los pasos descritos en su documentación. Instalamos con composer:
composer require 'codeception/codeception' --dev
Mi recomendación es no instalarlo de forma global, salvo que ya tengas claro que quieres levantar testings en muchos sitios.
Generamos toda la base de carpetas y código:
./vendor/bin/codecept bootstrap
Y por último crearemos el primer test:
./vendor/bin/codecept generate:cest acceptance First
Detalles de configuración ¶
Lo tenemos todo listo y en la carpeta tests/acceptance/FirstCest.php
tendremos alojado el escenario con el que vamos a empezar a jugar.
Antes de esto hay que realizar una pequeña modificación en la configuración específica de las pruebas de aceptación.
En tests/acceptance.suite.yml
tendremos esto:
actor: AcceptanceTester
modules:
enabled:
- PhpBrowser:
url: https://pastebin.com
- \Helper\Acceptance
step_decorators: ~
Codeception tiene mucha cuerda, así que no vamos a ver en detalle todo. Sólo queremos saber las bases del funcionamiento.
Si te puedes fijar en que la URL de las pruebas va a ser pastebin.com
. El popular sitio donde pegar texto para que otros lo vean será nuestra ‘víctima’.
Tipos de tests de aceptación ¶
Antes de continuar te cuento algo bastante importante. En Codeception hay dos tipos de tests de Aceptación.
- Los basados en PHPBrowser. No abrimos el navegador sino que lo simulamos con la librería
SymfonyBrowserKit
. Esto quiere decir que no tendremos la opción de ejecutar la web con JavaScript. - Los basados en WebDriver. Aquí si arrancamos un browser para ejecutar las pruebas. TIene compatibilidad con
Selenium
yPhantomJS
. No es difícil encontrar soluciones también parapuppeteer
.
Nos quedamos con el primero. Son más rápidas de ejecutar y todo lo que aprendamos en ellas nos servirán para las que si abren un Firefox o un Chrome.
Si te advierto que Codeception tiene una forma peculiar de hacer algunas cosas, con lo que aprovecha este desembarco iniciático para comprobar si te interesa incluirlo en el stack tecnológico de tus aplicaciones o mantenerlo de forma externa.
Para tu tranquilidad si te digo que se basa en el standard de facto: PHPUnit.
Primer tests de aceptación ¶
En nuestra clase de pruebas dejamos este código:
<?php
//tests/acceptance/FirstCest.php
class FirstCest
{
public function sendNewPastebin(AcceptanceTester $I)
{
$I->amOnPage('/');
$I->see('New Paste');
}
}
Ejecutamos el test:
./vendor/bin/codecept run acceptance FirstCest --steps
Nota: Las combinaciones para filtrar los tests en la línea de comandos son muy amplias. Si quieres echar un vistazo a todas sus opciones la documentación en línea es muy completa.
El resultado debería ser este:
Nuestro script ha emulado la carga de la página principal de pastebin y ha buscado que exista en algún sitio las palabras ‘New Paste’.
Ese método see
tiene muchísimas variantes, no dejes de buscar la más adecuada.
Usemos el formulario de creación de nuevos contenidos, que para eso estamos aquí.
<?php
class FirstCest
{
public function sendNewPastebin(AcceptanceTester $I)
{
$I->amOnPage('/');
$I->see('New Paste');
$I->fillField('paste_code', 'Prueba de Acceptance Testing');
$I->click('#submit');
}
}
Con fillField
rellenamos el campo textarea
con el atributo paste_code
(Codeception buscará el que mejor encaje, sino lo encuentra, protestará).
Escribimos un texto y terminamos pulsando el botón de publicar. En este caso, para que veas la polivalencia de Codeception, localizamos ese submit
por su atributo identificador id
.
Después del envío de formulario ¶
Completemos el proceso comprobando que todo ha sido correcto:
<?php
class FirstCest
{
public function sendNewPastebin(AcceptanceTester $I)
{
$I->amOnPage('/');
$I->see('New Paste');
$I->fillField('paste_code', 'Prueba de Acceptance Testing');
$I->click('#submit');
$I->seeInField('paste_code', 'Prueba de Acceptance Testing');
}
}
Tras hacer ‘click’ el tests esperará, sin que nosotros se lo tengamos que decir, a que cargue la siguiente página. Si estuviéramos en el otro tipo de test, el WebDriver
si podríamos establecer una espera. En PhpBrowser
nuestra prueba lee directamente del HTML.
Así que ahí solo tenemos que ver si en el campo paste_code
está escrito ese texto.
(Nota: No te lo he dicho antes, pero te recomiendo vivamente hacer este proceso manualmente tu por tu cuenta, para ver lo que se cuece antes de probarlo).
Capturas de pantalla en formato HTML ¶
Para que termines de creerte lo que hace todo esto, añadamos un paso más a la prueba:
<?php
class FirstCest
{
public function sendNewPastebin(AcceptanceTester $I)
{
$I->amOnPage('/');
$I->see('New Paste');
$I->fillField('paste_code', 'Prueba de Acceptance Testing');
$I->click('#submit');
$I->makeHtmlSnapshot();
$I->seeInField('paste_code', 'Prueba de Acceptance Testing');
}
}
Este nuevo método hará una captura en ese punto del HTML que está viendo el test al ejecutarse. Y la guardará en la carpeta tests\_ouput\_debug
.
Justo en la carpeta donde Codeception guarda los resultados también te encontrarás el HTML de la página que da fallo en el test (si así fuera). Te informa en consola, así que es imposible perderse.
Capturando datos y añadiendo aserciones ¶
Queremos capturar también datos de las páginas que cargamos. Esta página genera una nueva URL para cada publicación, así que nos interesa capturarla. Ahora lo añadimos al final del código con el método grabFromCurrentUrl()
y lo exponemos a la consola con expectTo
.
Puede también que a estas alturas ya hayas tenido problemas con el detector de ‘gente mala’ de pastebin. Tiene un férreo control de spam así que vamos a introducir una aserción más en el código para que nos devuelva un error si la página nos bloquea.
<?php
class FirstCest
{
public function sendNewPastebin(AcceptanceTester $I)
{
$I->amOnPage('/');
$I->see('New Paste');
$I->fillField('paste_code', 'Prueba de Acceptance Testing');
$I->click('#submit');
$I->makeHtmlSnapshot();
$I->dontSeeInTitle('Possible Spam Detected');
$I->seeInField('paste_code', 'Prueba de Acceptance Testing');
$uri = $I->grabFromCurrentUrl();
$I->expectTo('El alias de URL es ${uri}');
}
}
En efecto dontSeeInTitle
va a comprobar que en la etiqueta <title>
no se contenga ese texto. Si nos apareciera la página de control de ‘persona humana’ tendríamos un error.
Aquí tendríamos el resultado final:
Conclusión ¶
El testing es algo que tendemos a evitar hacer, y, ahí, nos equivocamos. En la sesión en directo que dedicamos a las pruebas unitarias la pregunta más recurrente de los asistentes fue precisamente: ‘¿Y esto como lo uso en un proyecto real?’.
Allí y aquí tenemos la primera piedra del camino.
Suscríbete a la Zona Premium para seguir caminando por ese sendero con toda la comunidad que está allí dentro.
Si te interesa este tema y quieres saber más, no dejes de contactar conmigo.
Escrito por:
Daniel Primo
12 recursos para developers cada domingo en tu bandeja de entrada
Además de una skill práctica bien explicada, trucos para mejorar tu futuro profesional y una pizquita de humor útil para el resto de la semana. Gratis.