Automatización de pruebas con Visual Testing

22 de noviembre de 2024

Introducción

El mundo del testing avanza a velocidad de crucero. Y con ello, surgen nuevas técnicas, herramientas, frameworks o estilos de pruebas.

Cuando pensamos en pruebas, se nos viene a la mente comprobar que todo funcione, que todo sea rápido, que todo tenga sentido… pero, ¿pensamos en lo que ve el usuario en su pantalla? Simplemente, lo que ve.

Quizás nuestra web de ecommerce funciona correctamente, es rápida e intuitiva gracias a nuestras pruebas… Pero imaginemos que en la última versión desplegada el botón de “pagar” quedó solapado por detrás de un nuevo banner y los usuarios no logran localizarlo fácilmente. Caen las ventas y por tanto nos preguntamos, ¿qué ha podido pasar si todo funciona correctamente?

Hasta que consigamos averiguar qué ha ocurrido y solucionar el problema, los usuarios no han quedado satisfechos debido a dificultades al realizar la compra, o se han dado por vencidos y no la han realizado, o lo que es peor… hemos perdido clientes de nuestra web que no sabemos si volverán.

Si pensamos que este error parece indetectable para las pruebas… estamos muy equivocados. Gracias a Visual Testing podríamos habernos ahorrado esta situación.

En este artículo, aprenderemos cómo se aplica en un caso de prueba real y hablaremos en detalle de las funcionalidades, ventajas, desventajas y todo lo relacionado a Visual Testing.

Sepamos un poco más sobre ello…

¿Qué es Visual Testing?

Visual testing es una técnica de pruebas que captura una web en un momento concreto para comprobar si el usuario la ve como se espera.

Comparando imágenes consigue detectar si hay elementos de la web que no se encuentran en el sitio o la forma en la que se esperaban.

¿Cuáles son sus funcionalidades principales?

Visual testing es potente debido a diversos aspectos:

  • Ofrece la seguridad y fiabilidad de validar a nivel visual nuestra web.
  • Las pruebas pueden ser completamente personalizables. Se pueden examinar las zonas que nos interesen en concreto, la vista actual en la que se encuentra el usuario dentro de una web o la web completa sin necesidad de utilizar el scroll.
  • Se pueden omitir partes y elementos de la web, esto nos ayuda a evitar banners y elementos dinámicos que varían constantemente en la web.
  • Funciona en cualquier navegador (firefox, chrome, etc), dispositivo (ordenadores, smartphones) ó sistema operativo (windows, android, etc).

¿Cuáles son sus casos de uso más habituales?

iStock-467068210

Su uso más habitual es detectar qué elementos concretos de una pagina web o la página en su totalidad, esté como se espera que esté y que ningún elemento se haya desplazado de posición, cambiado de color, de forma, tamaño o contenido.

Por ejemplo, esperamos que cuando un botón X sea cuadrado, de color azul y con un texto "Púlsame" de tamaño X, entonces, Visual Testing comprobará que estos atributos visuales sean los esperados en las siguientes ejecuciones de las pruebas, y lo mismo con cada elemento presente en la página.

Por eso, Visual Testing es un gran aliado en pruebas de regresión, teniendo imágenes bases de antemano (imágenes creadas en un momento concreto donde la página y los elementos estaban como esperamos) con las cuales podemos validar una página a nivel visual en ejecuciones posteriores.

Además, otro de los casos habituales es la validación visual en distintos dispositivos y/o navegadores. Cada dispositivo o navegador, renderiza de maneras distintas y eso puede causar desajustes visuales indetectables en el corto plazo. Además, controlar esto cada vez resulta más complicado debido a la gran variedad de dispositivos y navegadores que existen. Por lo tanto, tener pruebas de Visual Testing, en este caso, ayuda a cubrir que la web se muestra correctamente en los dispositivos que consideremos.

¿Dónde no es recomendable?

Hay momentos donde quizás incluir Visual Testing no es una buena idea. ¿Cuándo? Cuando el objetivo de las pruebas sea únicamente comprobar la funcionalidad de la web. Por lo tanto, este proceso hará que el mantenimiento de las pruebas sea más difícil y tedioso.

Si añadimos Visual Testing cuando este no es el objetivo de la prueba, estaremos añadiendo puntos de rotura innecesarios o lo que es peor, falsos resultados a nuestras pruebas. Un test fallido por Visual Testing, ya sea debido a un cambio en la maquetación de la web, banners o elementos dinámicos que no se han tenido en cuenta, contarán como errores cuando ese no era el objetivo, sino saber si la funcionalidad es correcta.

¿Cómo aplicamos Visual Testing a la vida real?

1_2ntKtVBowGdACso6Gcmy1A

Llegó el momento de diseñar un caso de uso real. Gracias a Javascript y CucumberJS, vamos a detallar paso a paso cada acción de un usuario en nuestra prueba en un lenguaje ordinario y amigable (más información sobre Cucumber).

WebDriverIO será el encargado de interactuar con el navegador e Image Comparison Service el servicio de Visual Testing que ejecutará nuestra comprobación visual.

La prueba trata de comprobar que un usuario observa la sección Contact en la home de la web de Sngular https://www.sngular.com/ correctamente.

Para la puesta en marcha...

El entorno necesitará:

  • JavaScript como lenguaje principal.
  • NodeJS como ejecutor de nuestro proyecto.
  • Nuestro IDE favorito para el manejo del código. Esto es personal, pero si no dispones de uno te recomiendo Visual Studio Code.
  • NPM como gestor de paquetes.
  • CucumberJS será el framework que nos hará entender con lenguaje cotidiano los pasos de las pruebas.
  • WebDriverIO será el marco de automatización que interactuará con el navegador.
  • Y para Visual Testing utilizaremos Image Comparison Service, un servicio desarrollado para WebDriverIO que se adapta completamente a él y realizará nuestras comprobaciones visuales.

¿Cómo funciona?

Diseno-sin-titulo-10

El proceso de Visual Testing se realiza a través de tres imágenes:

  • Una imagen de referencia o baseline, sobre la que se basan las pruebas para comprobar que todo se ve de forma correcta.

  • Una imagen actual que es generada por el test ejecutado. Esta imagen es la que se compara con la imagen de referencia.

  • Y una tercera imagen, la imagen de diferencia. Esta última imagen es un híbrido entre las dos anteriores. Resaltará en color los píxeles no coincidentes para mostrarnos que ha cambiado en la web.

¿Cuáles son las funcionalidades técnicas dentro de nuestro proyecto?

Anteriormente hemos hablado de las funcionalidades principales que nos aporta Visual Testing, pero… ¿que nos aporta a nivel técnico en nuestro proyecto?

  • La configuración está centralizada en un único archivo.

  • Las imágenes se generan en el tipo de resolución que queramos. Podemos establecer una resolución en concreto o que la detecte de forma automática.

  • Se hacen validaciones con una simple línea de código.

  • Existen multitud de librerías de Visual Testing para la mayoría de lenguajes o frameworks que utilizamos.

  • Totalmente adaptable a nuestro proyecto de pruebas funcionales, Visual Testing se integra perfectamente con otros tipos de pruebas.

  • Si no se dispone de una captura imagen de referencia, podemos indicar que la primera prueba ejecutada sea la referencia para las demás.

Conocer más funcionalidades técnicas.

Instalación

Disponemos del código en el siguiente repositorio, lo abrimos en nuestro IDE.

Abrimos la terminal y en el directorio raíz del proyecto instalamos las dependencias.

>npm install

Servicio de Visual Testing

Existen diversas herramientas para realizar pruebas de Visual Testing, pero de entre todas ellas, una de las mejores opciones es el servicio de Visual Testing ofrecido por WebDriverIO llamado Image Comparison Service.

Su configuración es rápida y sencilla.Basta con tener instalado el servicio como librería en nuestro package.json y añadir su configuración al archivo de configuración de WebDriverIO.

Una configuración estándar podría ser la siguiente:

['image-comparison',
   {
       baselineFolder: join(process.cwd(), '../sngular_visual_testing/screenshots/references/'), //Directorio donde se almacenan las imagenes de referencia

       formatImageName: '{width}x{height}_{browserName}_{deviceName}_{tag}', //Nombre de las imágenes. Podemos indicarle variables como vemos, para diferenciar su resolución, el navegador en el que se ejecutan, el dispositivo, si llevan alguna tag...

      screenshotPath: join(process.cwd(), '../sngular_visual_testing/screenshots/tests/'), //Directorio de las imagenes de referencia

savePerInstance: true, //Establecer a true si queremos guardar imágenes por instancia. Es decir, si se ejecutan en chrome se crea un directorio de chrome y se almacenan ahí.

autoSaveBaseline: true, //Establecer a true si queremos que sino existe imagen de referencia, la siguiente prueba se guarde como imagen de referencia.

blockOutStatusBar: true, //Establecer a true para bloquear la barra de estado y dirección durante las comprobaciones. Esto evita problemas de wifi, tiempo o estado de la batería. Solo para dispositivos móviles.

blockOutToolBar: true, //Establecer a true para bloquear la barra de herramientas. Solo para dispositivos móviles.

clearRuntimeFolder: true, //Establecer a true para eliminar la carpeta de “actual” y “diff” en la inicialización.

}]

Más opciones para expandir la configuración de Image Comparison Service.

A diferencia de otras herramientas, esta es open source y de las más completas. Podemos encontrar otras herramientas para javascript como BackstopJS, Jest Image Snapshot (esta última trabaja con jest) y otras con sus respectivas ventajas e inconvenientes.

Al tratarse de un servicio propio de WebDriverIO, su adaptación al código de WebDriverIO es completa.

Diseño de una prueba

Visual Testing en prueba funcional o en prueba visual

Visual Testing puede integrarse con las pruebas funcionales sin ningún tipo de problema. A continuación veamos dos ejemplos:

  • una prueba funcional reforzada con Visual Testing donde verificaremos que todos los elementos de la página en ese momento estén donde se espera además de comprobar que uno de los campos del formulario funciona correctamente.

  • una prueba exclusiva de comprobación visual sin analizar ninguna funcionalidad.

Prueba funcional reforzada con Visual Testing.
Scenario: Se muestra la descripción "Email" en el campo de email
   Given El usuario accede a la web de Sngular
When Acepta las cookies
   When Pulsa en Contact en el menú principal
   Then Se muestra la descripción "Email" en el campo de email

En este escenario se establece una condición dada para la prueba (GIVEN), se realizan interacciones con la web simulando a un usuario (WHEN) y por último, se realiza una comprobación visual junto a una comprobación funcional en el último step (THEN). Por lo tanto, gracias a Visual Testing, podemos reforzar una prueba enfocada en comprobar una funcionalidad con una prueba a nivel visual.

El Then sería el siguiente:

Then(/^Se muestra la descripción “Email” en el campo de email$/, async function () {
   //Esperar al elemento textContactUs
   let textContactUs = await browser.$(contact.textContactUs);
   await browser.waitUntil(() => textContactUs.isExisting());
   //FUNCIONAL
   //Comprobación del campo email.
   //Contiene el texto “Email*” como descripción comprobando el atributo ‘placeholder’.
let emailContactUs = await browser.$(contact.emailContactUs);
await browser.waitUntil(() => emailContactUs.isExisting());
await emailContactUs.getAttribute('placeholder').then(async function (descriptEmailContacUs) {
await expect(descriptEmailContacUs).toContain('Email*');
});

   //VISUAL TESTING
   //El formulario se muestra correctamente con la descripción del campo email.
   expect(await browser.checkScreen('Se muestra la descripción “Email” en el campo de email$/, async function', {
//Añadir todas las opciones para nuestra prueba visual
hideScrollBars: true 
})).toEqual(0);
});

Así pues, puede haber pruebas funcionales con Visual Testing y pruebas que su objetivo principal sea comprobar visualmente la web.

Prueba de Visual Testling
Scenario: Un usuario observa el formulario de Contact correctamente
 Given El usuario accede a la web de Sngular
 When Acepta las cookies
 When Pulsa en Contact en el menú principal
 Then El usuario observa el formulario de Contact correctamente

En este caso el escenario está enfocado en la comprobación visual de la web. Al igual que en el caso anterior, se establece una condición dada para la prueba (GIVEN), se realizan interacciones con la web simulando a un usuario (WHEN) pero por último en este caso (THEN), se realiza únicamente una comprobación visual de la web. No queremos saber si los campos del formulario funcionan o cumplen ciertos requisitos, sino si se muestran de la forma adecuada.

El Then sería el siguiente:

Then(/^El usuario observa el formulario de Contact correctamente$/, async function () {
   //Esperar al elemento textContactUs
   let textContactUs = await browser.$(contact.textContactUs);
   await browser.waitUntil(() => textContactUs.isExisting());

   //VISUAL TESTING
   //El formulario se muestra correctamente.
   expect(await browser.checkScreen('El usuario ha introducido su email en el formulario correctamente', {
       //Añadir todas las opciones para nuestra prueba visual
       hideScrollBars: true 
})).toEqual(0);
});

Dicho esto, partamos como ejemplo de la prueba exclusiva de Visual Testing.

Desarrollemos nuestra prueba visual.

Vamos a poner especial atención en el cuarto y último step, donde se realiza una prueba visual que comprueba que una vez que estamos en la sección Contact, la web completa se muestra como esperamos.

Existen tres formas de realizar Visual Testing con WDIO Image Comparison Service:

  • checkFullPageScreen para capturar la web completa incluido si tiene varias vistas.

  • checkScreen para capturar la vista de la web en la que nos situamos en ese momento.

  • checkElement para capturar un elemento en concreto.

En este caso, utilizaremos checkScreen para una captura completa de la web.

Then(/^El usuario observa el formulario de Contact correctamente$/, async function () {
 
   let textContactUs = await browser.$(contact.textContactUs); //Localizar algún elemento de espera antes de realizar la captura y asegurarnos que se realiza la comprobación visual en el momento adecuado.
   await browser.waitUntil(() => textContactUs.isExisting()); //Esperar a dicho elemento

   //Visual Testing
   expect(await browser.checkScreen('El usuario observa el formulario de Contact correctamente', { 
       hideElements: [ //En hideElements omitiremos los elementos que no queremos que aparezcan en la captura tanto en las pruebas como en la referencia principal.
           
       ],
       hideScrollBars: true }) //Con hideScrollBars omitimos la barra de scroll
).toEqual(0); //Con toEqual establecemos el margen de diferencia medido en porcentaje que queremos. Si lo establecemos en 0, cualquier mínima diferencia será considerada.
}); 

Ejecutemos.

Para comprobar el funcionamiento de Visual Testing vamos a simular que el título del formulario de Contact desaparece en la web, en realidad puede ser debido a un despliegue corrupto o a alguna funcionalidad desarrollada que lo provoque.

Realizaremos una primera ejecución correcta que guardará la imagen referencia, y a continuación, ejecutaremos de nuevo sin el elemento del título para comprobar que sucede y si nuestra prueba de Visual Testing nos avisa de que algo no cuadra.

Para ejecutar el test:

 >npx wdio wdio.conf.js

Una vez lanzado el test, cuando finalice; nos ofrecerá el siguiente resultado.

6

Observamos como se ha grabado el estado actual de la sección en una imagen. Almacenada en el directorio screenshot/references.

Una vez que tenemos una referencia, procedemos al simulacro de error. Vamos a omitir el título del formulario para comprobar que Visual Testing cumple su función.
Obtenemos el elemento y lo añadimos como hideElement en la prueba visual del último step.

var vs = await browser.checkScreen('El usuario observa el formulario de Contact correctamente', {
   hideElements: [
       textContactUs //Ocultamos el título para simular que ha desaparecido de la web
   ],
   hideScrollBars: true
});

Ejecutamos de nuevo nuestro test:

>wdio wdio.conf.js

Al finalizar observamos lo ocurrido. La prueba visual genera una nueva imagen denominada actual y como vemos a continuación, no muestra el título del formulario.

7-1

Esta imagen es contrastada con la imagen de referencia, y a partir de ambas se genera la tercera imagen. La imagen diff.

A continuación, observemos la imagen diff (comparativa entre la imagen referencia y la imagen actual). Vemos como se marca en color rosado la diferencia de las imágenes ya que en la prueba se esperaba encontrar ese título y no ocurrió así.

8

De esta forma, nos aseguramos que al usuario se le muestra la web exactamente de la forma que queremos.

Las imágenes podrán ser localizadas en sus respectivos directorios.

9

¿Cuáles son sus ventajas e inconvenientes?

Ventajas

Las principales ventajas de Visual Testing son…

  • El refuerzo y calidad que ofrecen a nuestras baterías de pruebas. Con Visual Testing tendremos la web controlada de forma visual y dormiremos tranquilos sabiendo que no hay elementos desmaquetados.

  • El ahorro de tiempo validando aspectos visuales de la web para diferentes navegadores y dispositivos. De esta forma podremos tener controlada la maquetación de nuestra web en cualquier dispositivo y asegurarnos que tanto el usuario que ve la web en un iPhone X, como el que la ve en un Samsung Galaxy, o el que prefiere un PC o tablet, ven la web correctamente.

Inconvenientes

Como todo, hay casos donde Visual Testing más que ayudar puede lastrar nuestra batería de pruebas… Su principal inconveniente es que no es buena idea implantar Visual Testing si el objetivo de las pruebas es únicamente funcional. ¿Por qué? Porque al igual que cualquier otra técnica que no se vaya a utilizar, lastrará de complejidad y puntos de roturas no necesarios a nuestras pruebas. Implantar cosas sin ningún objetivo, hará que las pruebas sean más complejas y difíciles de mantener y retrasará sus tiempos de ejecución. Por lo tanto, las pruebas deben ir orientadas a lo que se quiere probar. Visual Testing debe ser nuestro aliado si el objetivo es claro, comprobar lo que ve el usuario.

Conclusiones

Cada día los usuarios nos volvemos más exigentes con las webs y aplicaciones que manejamos. Sabemos que la tecnología avanza muy rápido y nos volvemos más exigentes con ella y si además sumamos la diversidad de plataformas y modelos de negocio en los que compiten las empresas un mal escaparate virtual puede ser la ruina para ellas. Por ello, la maquetación y la puesta en escena de la web tiene que ser lo más precisa y descriptiva posible de lo que se quiere transmitir. El objetivo es transmitir al usuario fiabilidad. La mejor empresa del mundo puede ser cuestionada si la web tiene elementos superpuestos, botones solapados, textos que salen de la pantalla, imágenes que no cargan… y para muchos de estos casos, Visual Testing es la respuesta.

Las pruebas funcionales nos ayudarán a saber que la web funciona, pero Visual Testing será nuestro gran aliado para no solo ofrecerle al usuario una web que funciona correctamente, sino que se muestra tal y como queremos transmitirle.

“Visual Testing ha llegado para quedarse.”

Bibliografía