Introducción
Si hablamos de Unit Testing
seguramente te resulte familiar, ... Es lo que vamos haciendo para generar piezas robustas de código, ... Eso sí, piezas por separado, ¿Qué pasa cuando las juntamos?... pues que pueden surgir problemas, aquí podemos seguir avanzando y hablar de pruebas de integración
, pero... ¿Y si pudiéramos ir un paso más allá? ¿Por qué no automatizar pruebas manuales con la aplicación real funcionando? Bienvenido al lado oscuro de QA 🤗.
Las pruebas de extremo a extremo (E2E) nos permiten probar aplicaciones web en tiempo real de forma automática, simulando la interacción de un usuario con la aplicación, es decir, es como si una persona estuviera interactuando con la aplicación y comprobando visualmente que obtiene el resultado esperado.
Lo potente de esta aproximación es que puedes lanzar las pruebas cuando quieras y sin tener un humano detrás para comprobar manualmente que todo ha salido como esperabas.
Una herramienta muy potente para realizar este tipo de pruebas es PlayWright (Microsoft). En este post vamos a ver cómo podemos configurar PlayWright en nuestro proyecto de Front para crear y ejecutar pruebas E2E automatizadas.
TL;DR;
PlayWright es una herramienta de automatización de pruebas de extremo a extremo que permite escribir pruebas en JavaScript, TypeScript y Python. Se basa en que tú interactúas mediante código con el navegador, como lo haría un usuario real (haciendo clic, escribiendo texto, etc.) y después podemos comprobar los resultados de la interacción leyendo el DOM.
Playwright es una herramienta de pruebas de caja blanca. No conoce los detalles de tu código, esto nos permite probar cualquier aplicación web, independientemente de la tecnología que utilices.
Para usar Playwright:
- Necesitas instalarlo en tu proyecto.
- Configurarlo correctamente.
- Definir tus pruebas.
- Lanzarlas y esperar resultados.
¿Con ganas de entrar en detalle? Sigue leyendo...
Paso 1: Entendiendo PlayWright y e2e testing
Cuando desarrollamos unit tests, estamos probando piezas separadas, o si me aprietas, podemos probar a hacer test de integración y probar un conjunto de ellas, pero... Esto no es suficiente, cuando desplegamos una aplicación, debemos de tener alguna garantía de que el usuario pueda completar flujos de principio a fin. Siempre puede haber fallos tontos que no sean fáciles de detectar con tests unitarios o de integración.
¿Qué se hacía en muchos casos? Tener a testers manuales, es decir, personas que se hacían un guion con pasos e iban manualmente probando la aplicación, es decir:
Arrancas la aplicación en un entorno de QA (test), preproducción, o incluso producción (se puede plantear ejecutar tests de end to end en producción).
Tienes un guion con unos pasos.
Prueba a hacer los pasos y vas anotando y comprobando que todo funciona como esperas.
Esto de primeras puede parecer algo asumible, pero a poco que tu proyecto avanza te encuentras que:
El proyecto crece y cada vez tiene más funcionalidad, y lo que es peor, introducir una nueva característica puede romper una anterior.
Hacer un test manual de una característica puede ser viable la primera vez, pero cuando quieres salir a producción, lo suyo es, poder testearlo todo. Imagínate si la aplicación crece cuanto pueden tardar en ejecutar manualmente todos los tests.
Y si hablamos que tenemos que ser ágiles y poder desplegar a producción varias veces al día, no puedes estar esperando a que un tester manual pruebe todo.
¿Y si pudiéramos pasar esos test manuales a código? Es decir, que un bot simulará que pinchas en un botón, que tecleas en un input y después comprobará que el resultado es el esperado. Un ejemplo simple:
- Un bot pincha en el input de usuario y teclea el email de una cuenta.
- El mismo bot pincha en el input de contraseña y teclea la contraseña.
- Y ahora busca el botón de login y pincha en él.
- Por último, comprueba que ha entrado en la aplicación y que el usuario está logueado (ha navegado a la página principal y en la cabecera de arriba a la derecha aparece el nombre del usuario).
Esto es lo que se conoce como End to End Testing o e2e Testing.
La primera vez, crear ese script automático nos va a costar más que ejecutar un test de forma manual, pero a la larga, nos va a permitir:
- Poder ejecutar esos tests de forma automática.
- Poder ejecutar esos tests de forma automática en cualquier entorno (QA, preproducción, producción), así como en diferentes navegadores.
- Poder ejecutar esos tests de forma automática en cualquier momento.
Paso 2: Instalando la herramienta
Como hemos comentado vamos a utilizar PlayWright para definir y lanzar pruebas e2e, es decir vamos a realizar pruebas en modo "caja negra": yo no sé en qué lenguaje o que detalles de implementación tiene tu solución, lo que voy a hacer es interactuar en el navegador con tu aplicación y comprobar que todo funciona correctamente ¿Cómo? Como si fuera un usuario real, es decir, voy a hacer clic en botones, rellenar formularios, comprobar que se muestran los datos esperados, etc.
Así que, ¿Cómo se instala PlayWright? Aquí viene la parte buena: la instalación de Playwright es sencilla y se realiza a través de npm o yarn, como cualquier otro proyecto Node.js. Así, evitamos instalaciones complejas con múltiples pasos y asistentes. Tienes dos opciones para organizar el proyecto de pruebas:
- Crear el proyecto de E2E dentro del repositorio principal de frontend Puedes crear una subcarpeta dentro de tu proyecto frontend para centralizar las pruebas E2E. Una estructura típica sería:
/proyecto
/frontend
/e2e
- Crear un proyecto de pruebas como repositorio independiente (algo común en equipos de QA especializados), pero en este caso tendrías que tener en cuenta que tendrías que tener una forma de comunicar el proyecto de e2e con el proyecto de front end, es importante considerar cómo se comunicará con el proyecto frontend. Una práctica recomendada es utilizar una variable de entorno o un archivo de configuración que permita enlazar ambos proyectos de manera sencilla, o bien que el equipo de QA trabaje directamente sobre una versión desplegada en un entorno concreto, al que normalmente se le llama entorno de QA o entorno de testing. Esto último facilita que las pruebas se ejecuten sobre una versión estable de la aplicación sin interferir con el desarrollo en curso.
Nos ponemos manos a la obra, ya tenemos nuestra carpeta vacía esperando a que inicialicemos nuestro proyecto de pruebas. Para ello, abrimos un terminal y ejecutamos el siguiente comando desde la terminal de bash o ms-dos:
Si somos de npm:
npm init playwright@latest
Si somos de yarn:
yarn create playwright
Esto va a realizar una serie de pasos por nosotros:
Configura el proyecto de Playwright: Crea una estructura básica de archivos para las pruebas, con carpetas y archivos de ejemplo que te ayudarán a comenzar.
Descarga automáticamente los navegadores: Al ejecutar el comando, Playwright también descarga versiones específicas de los navegadores (Chromium, Firefox y WebKit) que necesita para ejecutar las pruebas. Esto asegura que las pruebas se realicen de manera consistente en los entornos adecuados.
Incluye archivos de configuración: Crea archivos de configuración iniciales (playwright.config.js) para personalizar y ejecutar las pruebas.
Cuando le damos a enter, la herramienta nos hará una serie de preguntas:
√ Where to put your end-to-end tests? · e2e
¿ En que carpeta vamos a crear tus tests? Lo normal es poner e2e o tests, pero puedes poner el nombre que quieras.
Add a GitHub Actions workflow? (y/N) · false
Uno de los puntos fuertes del e2e testing automático es que puedes incluirlo en tu ciclo de CI/CD (integración continua y despliegue continuo). ¿Esto qué es? Pues, que por ejemplo, cuando vayas a subir código a tu repositorio o quieras mezclar a tu rama principal.
Automáticamente, se ejecuta la batería de pruebas e2e y, si todo está correcto, se permite mezclar la rama o subir a producción.
En este paso de creación vamos a decirle que no. En otro post de esta serie os comentaremos cómo configurarlo de forma manual y así poder tener un control más fino.
√ Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n)
Por último, nos pregunta si queremos instalar los navegadores necesarios para ejecutar las pruebas. Es recomendable aceptar (opción "Y") en este momento, ya que, si decidimos no instalarlos ahora, tendremos que hacerlo manualmente más adelante usando el comando npx playwright install.
¿Y por qué tengo que instalar navegadores si ya los tengo en mi máquina?
Playwright instala versiones específicas de cada navegador (Chromium, Firefox, y WebKit) que han sido verificadas para funcionar de manera consistente con su entorno de pruebas. Esto asegura que las pruebas sean estables y predecibles, independientemente de las versiones que tengas instaladas localmente o de las actualizaciones que reciban esos navegadores en el futuro, además estas versiones personalizadas de los navegadores permiten evitar posibles inconsistencias entre máquinas de desarrollo o en entornos CI/CD, asegurando que las pruebas se comporten igual en cualquier entorno en el que se ejecuten.
Una vez ejecutado este wizard, nos ha tenido que quedar una estructura de carpetas parecida a lo siguiente:
/Mongo-Modeler
/e2e
/src
/playwright.config.js
/package.json
paso 3: Configurando PlayWright
Ya tenemos nuestro proyecto e2e inicializado y PlayWright, nos queda:
- Configurarlo para que sepa contra qué sitio web van a correr las pruebas.
- Definir una prueba e2e.
Ahora toca configurarlo para poder ejecutar las pruebas de nuestro proyecto.
Vamos a realizarlo sobre el proyecto Open Source Mongo Modeler.
En este caso, hemos decidido ejecutar los e2e test directamente desde el entorno de desarrollo, por lo que tenemos que indicarle a playwright:
- Cómo levantar ese servidor de desarrollo (en el caso de Mongo Modeler se arranca con el comando
npm run dev
). - Contra que URL va a correr las pruebas (en el caso de Mongo Modeler la aplicación corre en local en
localhost:5173
).
Está opción es buena para poder probar los e2e tests en local, e incluirlo en tu ciclo de integración continua, también hay equipos de QA que prefieren tenerlo todo en un entorno de servidor y simular que estamos tirando contra entorno real.
playwright.config.ts
+ const BASE_URL = 'http://localhost:5173/';
export default defineConfig({
testDir: './E2E',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
+ baseURL: BASE_URL,
trace: 'on-first-retry',
},
webServer: {
+ command: 'npm run dev',
+ url: BASE_URL,
- url: 'http://127.0.0.1:3000',
reuseExistingServer: !process.env.CI,
},
Y ahora en el package.json
añadimos el comando para ejecutar los tests e2e:
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives
--max-warnings 0",
"preview": "vite preview",
"format": "prettier --write .",
"test": "vitest",
"prepare": "husky || \"No need to install husky\"",
"tsc-check": "tsc --noEmit",
+ "e2e": "playwright test --ui"
},
Aquí le indicamos que levante playwright y que use la interfaz de usuario, en artículos siguientes veremos otra opción para ejecutar los tests sin interfaz de usuario, esto es muy útil cuando queremos integrarlo en un entorno de integración continua, o si queremos añadirlo como un paso previo a un commit o push.
Ya estamos listos para crear nuestro primer test e2e y ejecutarlo, vamos a por el siguiente paso.
paso 4: Creo mi primer test e2e
Si lanzamos ahora los tests e2e, fallarían, porque no hay ningún test definido, vamos a crear uno simple.
Cuando arrancamos la aplicación, se muestra una ventana de landing en la que hay un botón que dice "Launch MongoDB Designer", cuando pulsamos ese botón, nos redirige a la página que contiene el editor.
¿Qué vamos a probar?
- Navegamos a la raíz del proyecto.
- Pulsamos en el botón "Launch MongoDB Designer".
- Comprobamos que, en efecto, navega a la ruta "/editor.html".
Esta sería la página de landing
Esta sería la página del editor
El comportamiento esperado:
Para definir este caso:
- Debajo de la carpeta
e2e
. - Creamos el fichero
launch-mongodb-designer-link.spec.ts
(spec
viene despecification
, también podremos usartest
).
Ya que tenemos el fichero, le añadimos el siguiente contenido
./e2e/launch-mongodb-designer-link.spec.ts
import { test, expect } from '@playwright/test';
test('navigates to and verifies MongoDB Designer URL', async ({ page }) => {
await page.goto('');
await page.getByRole('link', { name: 'Launch MongoDB Designer' }).click();
await expect(page).toHaveURL('http://localhost:5173/editor.html');
});
¿Qué estamos haciendo aquí?
- Definimos un test y le indicamos con una descripción en texto que cubre.
- Indicamos que es un test asíncrono (tenemos que esperar a que se resuelvan acciones).
- Le indicamos que vaya a la raíz de la aplicación.
- Buscamos el enlace que tiene el texto "Launch MongoDB Designer" y hacemos clic (se puede buscar un elemento por muchos criterios, en este caso lo hacemos por el rol y el nombre, también se pueden buscar por id, ...).
- Una vez encontrado ese botón, simulamos un clic del usuario.
- Una vez que se ha hecho clic, comprobamos que la navegación se ha realizado, y que en el navegador está en la URL esperada.
Ya que tenemos el test, solo tenemos que ejecutar desde la línea de comandos npm run e2e
.
npm run e2e
Al lanzar esto desde el terminal, podemos ver que se abre la UI de playwright.
Ahora podemos darle al botón play o la tecla F5 del teclado y lanza todos los test. Como podemos ver tiene el Check de éxito.
En este caso MongoModeler
es una aplicación pura de Front, ¿Qué pasaría si tuviera que interactuar con una API Rest o similar? Aquí tengo varias estrategias:
- Puedo definir mocks para respuestas específicas de la API.
- Puedo definir un servidor de Mock que tenga los mismos contratos que la API real.
- También puedo tirar contra entorno real o QA
Todo esto lo veremos en los siguientes posts de esta serie.
Repositorio de ejemplo
Te dejo un enlace al proyecto de github con la configuración completa:
Enlace al repositorio con el proyecto y su configuración completa
Conclusión y siguientes pasos
Al arrancar un proyecto, todo puede parecer muy sencillo, desarrollas un par de ventanas, tienes tus pruebas unitarias, manualmente haces un par de comprobaciones y ya estamos listos, pero a poco que el proyecto crece, estos checks van tomando más tiempos y lo que es peor, metiendo un cambio puedes romper accidentalmente otras cosas.
Es por eso que es importante contar con pruebas automatizadas, y en este caso, con pruebas E2E. Con Playwright, puedes automatizar estas pruebas de extremo a extremo de manera sencilla y eficiente, y asegurarte de que tu aplicación funcione correctamente en cada actualización.
En el siguiente post de esta serie vamos a ver cómo integrar Playwright en un proceso de CI/CD pudiendo lanzar estas pruebas cada vez que vayas a levantar una Pull request.
Sobre mí
Hola, me llamo Fran y soy desarrollador Front End + QA, si quieres conectar conmigo, te dejo aquí mi perfil de Linked in, ¡encantado de conectar!
Top comments (0)