Introducción al Testing E2E

Karla Cabañas

August 17, 2023

Introducción:

Existen varios tipos de pruebas que se utilizan en el desarrollo de software para garantizar la calidad del producto final. Entre ellos se encuentran las pruebas unitarias, las pruebas de integración, las pruebas estáticas y las pruebas end-to-end.

  • Pruebas End-to-End (E2E): Este test verifica todo el flujo de una aplicación desde el inicio hasta el final, simulando el comportamiento del usuario en un escenario real.
  • Pruebas de Integración (Integration): Verifican la interacción y la comunicación entre diferentes componentes y módulos de una aplicación.
  • Pruebas Unitarias (unit): Prueban unidades individuales de código, como funciones o métodos, de manera aislada del resto de la aplicación.
  • Pruebas Estáticas (static): Revisan el código fuente en busca de errores y vulnerabilidades sin ejecutar el programa, a través de revisiones de código y análisis estático.

En la fase de desarrollo de aplicaciones, una de las prácticas fundamentales para garantizar la calidad del software es el testing. Entre los diferentes tipos de testing, el Testing End-to-End (E2E) destaca por simular el comportamiento del usuario real al interactuar con la aplicación. En este artículo, exploraremos qué es el E2E testing, cómo funciona y cómo puede beneficiar el desarrollo de aplicaciones.

Desde hace varios años, la librería de Cypress ha estado disponible. Es una de las herramientas más populares para realizar este tipo de pruebas porque permite hacerlo con el navegador Chrome, el cual es ampliamente utilizado por los desarrolladores y es conocido por ser rápido y seguro.

¿Qué es el Testing End-to-End (E2E)?

La característica distintiva del test E2E es que se enfoca en la funcionalidad de la aplicación desde una perspectiva global, sin preocuparse por los detalles internos de su implementación. No se trata de probar funciones o métodos individuales, como en el Unit Testing, ni de verificar la integración entre componentes específicos, como en el Integration Testing. En cambio, el E2E Testing se concentra en el resultado final, asegurando que todos los componentes trabajen juntos de manera efectiva para cumplir con los requisitos y expectativas del usuario.

El proceso de un test de End-to-End implica la simulación de acciones típicas del usuario, como hacer clic en botones, completar formularios, navegar por diferentes páginas o interactuar con elementos de la interfaz. Estas pruebas se ejecutan en un entorno similar al de un usuario real, utilizando un navegador web o una interfaz gráfica, y pueden implicar interacciones con bases de datos, servicios web y otros sistemas externos.

El objetivo principal del E2E Testing es asegurar que la aplicación funcione correctamente en todas sus partes y que las diferentes funcionalidades se integren sin problemas. Además, estas pruebas también pueden ayudar a identificar posibles problemas de rendimiento, usabilidad y accesibilidad.

Si bien el testing E2E es esencial para garantizar la calidad y el correcto funcionamiento de una aplicación, también puede ser más complejo y llevar más tiempo de configuración y ejecución en comparación con otros tipos de pruebas más focalizadas. Sin embargo, su importancia se enfoca en su capacidad para proporcionar una visión global del producto, permitiendo a los desarrolladores y equipos de calidad detectar problemas y asegurarse de que la aplicación satisfaga las necesidades de los usuarios finales.

Ventajas del E2E Testing en Cypress

  • Time Travel:Cypress tiene una función de "Time Travel" que permite a los desarrolladores ver cada paso de la prueba mientras se ejecuta. Esta característica única facilita la depuración y el análisis de pruebas, ya que los desarrolladores pueden ver exactamente lo que está sucediendo en cada momento. Pueden inspeccionar el estado de la aplicación en cualquier punto durante la ejecución de la prueba, lo que simplifica la identificación de errores y el entendimiento de los problemas en la aplicación.
  • Debuggability:Cypress es fácil de depurar. Ofrece una interfaz visual que permite a los desarrolladores examinar el estado de la aplicación, los valores de las variables y otros detalles importantes. Esto facilita la identificación y resolución de problemas, mejorando la eficiencia y la productividad en el desarrollo.
  • Real time reloads:Una de las características más destacadas de Cypress es su funcionalidad de recarga en tiempo real. Cada vez que se realizan cambios en el test o en el código de la aplicación, Cypress vuelve a ejecutar automáticamente las pruebas afectadas de forma inmediata. Esto permite a los desarrolladores obtener una retroalimentación instantánea sobre los cambios realizados y verificar si introdujeron algún error en la aplicación.
  • Automatic waiting:"Espera automática" integrada, lo que significa que no es necesario agregar pausas o esperas explícitas en el test para esperar que los elementos de la página se carguen o las acciones se completen. Cypress detecta automáticamente cuándo una acción espera respuesta de la aplicación y aguarda hasta que los elementos estén disponibles y las tareas se completen antes de seguir con el test. Esto previene problemas comunes de tests inestables y simplifica la escritura de pruebas más robustas y confiables.

Creando un Test E2E con Cypress

Este documento presenta un ejemplo práctico de cómo crear una prueba E2E utilizando la herramienta Cypress. Se muestra cómo configurar el entorno de prueba, escribir la prueba y ejecutarla para verificar la funcionalidad de una función específica de la aplicación.

1. Para instalar Cypress en nuestro proyecto, podemos utilizar tanto yarn como npm. En este caso, utilizaremos npm durante todo el proceso.

npm install cypress --save-dev

2. Antes de abrir el proyecto, necesitamos configurar los scripts en nuestro package.json, en donde agregaremos:


"scripts": {
		//...demás scrips
		"cypress:open": "cypress open"
	},


⚠️Si no se agregan los scripts, el proyecto se deberá ejecutar con un comando más largo

./node_modules/.bin/cypress open

3. Para ejecutar el proyecto, necesitamos ejecutar el “modo open” que es el siguiente comando en la consola:

npx cypress open

Se abrirá una ventana, similar a la que se muestra en la imagen. Permitirá configurar el testing e2e y mostrará el proyecto en el que estamos trabajando y su versión actual.

4. Después de eso, el navegador nos pedirá que seleccionemos dónde queremos ejecutar nuestro proyecto con pruebas E2E. A partir de ahí, podemos empezar a ver nuestras pruebas en la carpeta donde las colocamos.

5. Se abrirá una ventana del navegador Chrome para ejecutar las pruebas en Cypress. En la imagen se muestra la carpeta "cypress/e2e" donde se guardan los proyectos. En este caso, hay tres subcarpetas con códigos para ejecutar las pruebas.

En este mismo paso, se presentará un ejemplo que viene integrado en Cypress. En él, se muestra que las pruebas pasaron exitosamente. En caso de que fallaran, se indicaría dónde se produjo el fallo.

Además tenemos el "modo run" en el cual se muestran en la consola los estados de las pruebas. Para ejecutar las pruebas en modo headless (en la línea de comandos), utiliza el siguiente comando

npx cypress run

Ejemplos de con código

Para poder dar la ejecución de Cypress testing e2e, se explicará brevemente algunos códigos y es para una app que esté en modo local, el código se puede modificar a como se desee usar.

Describe en Cypress se utiliza para agrupar un conjunto de pruebas relacionadas en un mismo ámbito. Proporciona una forma de organizar las pruebas y agruparlas según su funcionalidad o área específica de la aplicación que están probando.

BeforeEach es un bloque de código que se ejecuta antes de cada prueba (o caso de prueba). En este caso en particular se usa para solo hacer el login una vez dentro del código del test.

⚠️ El ejemplo que se da es el mismo código, pero dividido en dos partes para explicar mejor lo que hace cada una.

Parte 1:



// cypress/e2e/example.cy.tsx

describe('Login', () => {
beforeEach(() => {
		cy.visit('http://localhost:3000');
		cy.get('.btn-password').click();
		cy.get('.email').type('example@kranio.cl');
		cy.get('.password').type('ASdf1234');
		cy.get('.login-button').click();
});
//...it
//...it
});

⚠️ Como buena práctica es mejor establecer una baseUrl y así llamamos al visit

cy.visit('/');

📌 También puedes buscar directamente el tipo de elemento que deseas en el DOM. Por ejemplo:

cy.get(Input[placeholder='Username']).type('example@kranio.cl')

Para obtener más información sobre la usabilidad de "get", consulta https://docs.cypress.io/api/commands/get

Parte 2:



it('Ingresa un numero al input y presiona el buscar', () => {
		cy.origin('http://localhost:3000', () => {
			cy.contains('Aceptar').click();
				cy.get('Input[placeHolder="N° del contenedor"]').type('1234567');
				cy.get('button[type="submit"]').contains('Buscar').click();
		});
	});

Resumiendo lo que hace el código:

  • En primer lugar, se proporciona una descripción general de lo que hará el código. Luego, en la sección de cy.origin('<http://localhost:3000>'..), se asegura de que la página que estamos viendo sea localhost:3000.
  • Después, busca un botón que diga "aceptar". En este ejemplo, era un modal de alerta que contenía este botón.
  • A continuación, se puede ver que se agrega un numero de contenedor en un input y se presiona el botón de buscar, en donde ambos se encuentran por su placeholder y su type.

💡 cy.contains Este comando permite encontrar elementos que contienen un texto específico y luego realizar acciones en ellos, como hacer clic, escribir en ellos o verificar su presencia.

💡 cy.get Se puede usar este comando para buscar elementos según su selector (como identificadores, clases, etiquetas, etc.) y luego realizar diversas acciones en esos elementos, como hacer clic, escribir en campos de entrada o verificar sus propiedades.

Parte 3:


it('Se ven las estadisticas', () => {
		cy.origin('http://localhost:3000', () => {
			const totalContainerValue = 10; 
			const totalOsValue = 30;
			const totalPiecesValue = 20;

			cy.contains('Aceptar').click();
			cy.get('h3').should('be.visible'); 
			cy.get('h6').should('be.visible'); 

			cy.get('h6:contains("Total contenedores")').should('be.visible');
			cy.get('h6:contains("Total OS")').should('be.visible');
			cy.get('h6:contains("Total Piezas")').should('be.visible');

			cy.get(`h3:contains(${totalContainerValue})`).should('be.visible');
			cy.get(`h3:contains(${totalOsValue})`).should('be.visible');
			cy.get(`h3:contains(${totalPiecesValue})`).should('be.visible');

		});
	});


💡.should('be.visible') esta línea de código se usa para asegurarse de que ciertos elementos de la página sean visibles según lo previsto.

Resumiendo lo que hace el código:

  • Se le pasaron las props del componente que estamos testeando a este código. Los datos en ellas son los mismos que el usuario visualiza. Para verificar esto, primero debemos aceptar el modal de alerta y comprobar si los h3 y h6 están en nuestra página web. Luego, podemos verificar si los textos también están presentes.

.skip para poder pausar uno o más tests en particular. .

only solo se ejecutará esta prueba, y se ignorarán todas las demás pruebas en ese archivo de prueba.

✅Para más información sobre cypress E2E

Conclusión: Para resumir el articulo, el testing End-to-End (E2E) es una práctica fundamental en el desarrollo de software para garantizar la calidad y el correcto funcionamiento de una aplicación desde la perspectiva del usuario final. A diferencia de otras pruebas que se enfocan en componentes individuales o en la interacción entre ellos, el E2E testing verifica el flujo completo de la aplicación, simulando las acciones de un usuario real.

Karla Cabañas

August 16, 2023

Entradas anteriores