Detectar cambios visuales en una interfaz puede ser complicado cuando se trata de detalles pequeños como un padding, un margin o un texto que se movió sin previo aviso. El visual testing permite automatizar esa comparación y descubrir diferencias que al ojo humano podrían pasar desapercibidas. Con Cypress y un plugin específico, es posible capturar snapshots de la pantalla y compararlos entre ejecuciones para identificar cualquier regresión visual.
¿Qué es el visual testing y por qué importa?
El visual testing se refiere a la práctica de probar cambios en la UI de forma automática [0:22]. A diferencia de las pruebas funcionales que validan comportamiento, estas pruebas comparan imágenes para encontrar diferencias visuales. Un botón que se desplazó dos píxeles, un color que cambió o un elemento que dejó de renderizarse correctamente: todo eso lo puede detectar una prueba visual.
Cypress no ofrece esta funcionalidad de forma nativa, pero gracias a su sistema de plugins es posible extender sus capacidades [0:44]. El plugin que se utiliza es cypress-image-snapshot, una librería que se instala como dependencia de desarrollo.
¿Cómo se instala el plugin cypress-image-snapshot?
Desde la terminal se ejecuta la instalación con npm. Sin embargo, al trabajar con Cypress 10 puede aparecer un error de dependencias porque el plugin espera una versión específica y la comparación de versiones falla [1:14]. La solución es usar la bandera --legacy-peer-deps, que le indica a npm que ignore esas restricciones de compatibilidad y proceda con la instalación [1:40].
Una vez instalado, la configuración requiere dos pasos:
- Archivo de configuración de Cypress: se importa
addMatchImageSnapshotPlugin desde cypress-image-snapshot/plugin y se invoca pasándole los parámetros on y config [2:05].
- Archivo de commands: se importa la librería para registrar el comando personalizado
matchImageSnapshot [2:30].
¿Qué opciones de configuración existen para los snapshots?
Dentro del archivo de commands, al registrar el plugin se le pasa un objeto con varias propiedades importantes [3:05]:
- failureThreshold: define la tolerancia al fallo. Un valor de
0.03 representa el 0.03% de diferencia permitida.
- failureThresholdType: puede ser
pixel o percent. Usar percent permite trabajar con porcentajes de cambio.
- customDiffConfig: permite definir el threshold a nivel de píxel individual para mayor precisión.
- capture: configurado como
viewport captura únicamente lo visible en pantalla, no toda la página renderizada [3:40].
Un detalle que surgió durante la clase fue que configurar 0.3 en lugar de 0.03 significa treinta por ciento de tolerancia en vez de tres por ciento, lo cual es una diferencia enorme en los resultados [7:10].
¿Cómo funciona la comparación de snapshots?
Al ejecutar la prueba por primera vez, el plugin genera un snapshot base: una captura de pantalla que se almacena en una carpeta llamada snapshots [4:35]. En las ejecuciones posteriores, cada nueva captura se compara contra esa imagen original.
Si hay diferencias, la prueba falla y se genera un archivo en diff_output que muestra en rojo las áreas donde se detectaron cambios [5:25]. El reporte incluye:
- Diferencia en píxeles.
- Diferencia en radio.
- Diferencia en tamaño.
- Estado de aprobación o rechazo.
Cuando el retry está habilitado en Cypress, las pruebas fallidas se reintentarán automáticamente, lo cual es importante tener en cuenta porque puede extender el tiempo de ejecución [6:20].
¿Cómo se actualizan los snapshots cuando cambia la UI a propósito?
Existen dos formas de actualizar un snapshot. La primera es borrar manualmente la imagen almacenada para que se regenere. La segunda, más recomendable, es crear un script en el package.json que ejecute Cypress con una variable de entorno especial [7:40]:
"update:snapshot": "cypress open --env updateSnapshots=true"
Al correr este comando, el plugin detecta las diferencias y actualiza automáticamente las imágenes base. Esto es útil cuando los cambios en la interfaz son intencionales y se necesita establecer un nuevo punto de referencia [8:50].
¿Se puede hacer visual testing de un solo elemento?
No es necesario capturar toda la pantalla. Es posible encadenar el comando matchImageSnapshot a un elemento específico [9:40]. Por ejemplo, seleccionar un elemento que contenga el texto "Bulbasaur", verificar que sea visible y luego tomar su snapshot:
javascript
cy.contains('Bulbasaur').should('be.visible').matchImageSnapshot();
Esto genera una captura exclusiva de ese componente, permitiendo hacer pruebas de regresión visual mucho más granulares y enfocadas.
Un consejo valioso para el debugging: cuando no encuentres un error, explícale a alguien lo que estás haciendo. El simple acto de verbalizar el problema muchas veces te lleva a la solución [10:30]. Y si eso no funciona, despéjate, camina y regresa con la mente fresca. Los errores en visual testing suelen estar en detalles pequeños que pasan desapercibidos hasta que los miras con otros ojos.