Tests E2E con Jest y Puppeteer

Para garantizar la calidad del código

Pablo Cumpián Díaz
DotTech
3 min readApr 16, 2020

--

Photo by pixpoetry on Unsplash

Introducción

El testing E2E nos permite comprobar las funcionalidades de todo nuestro sistema. Tener tests E2E sólidos desde un principio, y nuestros casos de uso bien definidos, nos permite dar muestra de que nuestro software funciona según lo esperado y que seguirá funcionando bien según lo vayamos ampliando o refactorizando. Esto se conoce como testing regresivo.

Dentro del mundo node.js tenemos un tándem muy especial y completo para llevar a cabo esta tarea: Jest y Puppeteer. Se trata de dos bibliotecas ya conocidas por muchos en el mundillo. En este artículo se presupone un conocimiento mínimo de los métodos y objetos de ambas, ya que que se va a explicar un proceso de refinado de una suite de testing. Igualmente, el código que resulta de su uso es lo suficientemente legible para entenderlo bien.

Preparativos

Dependencias

Si buscas acerca del tema vas a encontrar muchos posts en internet que te indicarán que, junto a las bibliotecas, instales un preset para node.js llamado jest-puppeteer, el cual “insertará” en tus suites de jest un objeto browser y otro objeto page para que hagas las interacciones.

Personalmente, es una opción que no me gusta ya que equivale a utilizar variables globales y a una ruptura en la secuencia de nuestro código nada más empezar. En lugar de eso, propongo crear manualmente estos dos objetos, como se muestra a continuación:

Creando los objetos browser y page

Al hacerlo así, estamos contando la historia desde el principio: en primer lugar construimos los objetos con los que vamos a jugar. Además, nos falta por añadir un elemento del que no hemos hablado, el servidor de nuestra app:

Creando el objeto server

Así pues, ahora tenemos a todos nuestros actores en escena, sin dependencias innecesarias.

CTRL+R, CTRL+R, CTRL+R, CTRL+R…

Un truco que siempre me gusta repetir es añadir un beforeEach con un refresco de la página para hacer un reload en caso de que así lo requieran los tests:

beforeEach() con refresco de la página

Un test simple con interacciones

Normalmente nos encontraremos con scripts que interactúan con el navegador de forma secuencial. Vamos a verlo con un ejemplo divertido: una declaración de la renta muy tonta (algo propio de estas fechas):

Test de la declaración de la renta

Genial, pero se puede mejorar. Podemos hacer que los primeros inputs se obtengan de forma concurrente, usando Promise.all:

Usando Promise.all en lugar de await

Así damos la opción al runtime de realizar las primeras interacciones de forma concurrente, y después hacer el submit y comprobar que obtenemos la respuesta esperada.

Distintos tests cases para un mismo código

Podríamos reutilizar este código para añadir los tests cases según se nos ocurran o queramos explorar lo que cubre la app. Para ello vamos a usar los table-driven tests que nos proporciona Jest:

Ejemplo de un test dirigido por tabla

De esta forma, usando los string templates de JavaScript para modelar nuestra tabla con los parámetros del test, no necesitamos hardcodear los test, sino que podemos reutilizar nuestro código anterior para cada caso, y además hemos conseguido desacoplar operaciones y datos. Esto nos proporciona dos beneficios:

  1. El código es más legible, ergo comprensible.
  2. Añadir nuevos casos de prueba es más sencillo que en el código anterior.

Conclusión

Hemos visto una primera aproximación al testing E2E con Jest y Puppeteer: crear los objetos con los que interactuar, una refactorización para hacer nuestras interacciones asíncronas y el uso de tests dirigidos por tablas para poder añadir más casos reutilizando nuestro código. A partir de aquí quedan muchas opciones por explorar…

¿Qué tal realizar cada caso en ventanas separadas para poder realizar los tests completos de forma asíncrona?

--

--

Pablo Cumpián Díaz
DotTech

Computer Science student at @UNED . Writing about #golang and #javascript.