Visual AI con Applitools Eyes SDK: Automated Visual Testing

, , ,

En ALTEN somos conscientes que tenemos que estar siempre mejorando, optimizando y descubriendo nuevas formas de asegurar la calidad de nuestras aplicaciones y desarrollos. Eso nos hace estar al tanto de todas las herramientas y procesos que estén disponibles para lograr este fin.

En este post trataremos el concepto de Visual Testing automatizado, sus beneficios, las principales herramientas y los enfoques actuales con Inteligencia Artificial (Visual AI). Por último, nos centraremos en un ejemplo práctico usando la herramienta cloud basada en Visual AI: Applitools.

Definición de Visual Testing

Podríamos definir Visual Testing como parte de una estrategia de pruebas contra la interfaz de usuario (UI) que consiste en la evaluación/verificación de una captura de pantalla de una aplicación contra una esperada por diseño, siendo su principal objetivo encontrar Bugs visuales (fuentes, layouts, problemas de renderizado, etc.) y arreglarlos antes que estos pasen a producción.

El diseño de estas pruebas está orientado a detectar estos Bugs Visuales y hay muchos procesos que incluso las incluyen dentro de las pruebas funcionales como verificaciones o dedican planes de pruebas específicos. Los métodos de ejecución son, al igual que las pruebas funcionales, manual o automatizado. En el caso de la automatización, esta complementará al ojo humano.

Automated Visual Testing vs Functional Image-Based Automation

Es importante en este punto destacar que las herramientas de visual testing no son herramientas diseñadas ,en principio, para localizar elementos visuales en la pantalla, darnos una posición y hacerles click o extraer datos de la pantalla como texto (OCR) como podrían sí hacen Sikuli o EggPlant con el objetivo de completar un flujo funcional. Aunque herramientas de Visual Testing como AppliTools lo tienen, ya sería más bien un testing funcional y no Visual Testing.

Enfoque clásico vs enfoque actual con herramientas de Inteligencia Artificial (Visual AI)

En un enfoque tradicional básico se utilizaban algoritmos de comparación de píxeles. Estos daban bastante falsos positivos/negativos debido a que son sensibles a la profundidad de píxeles, a la resolución del monitor, etc.

Actualmente se ha mejorado este enfoque mediante herramientas de Inteligencia Artificial (Visual AI) que las hacen más fiables y bajan los falsos positivos/negativos. Para ello utilizan algoritmos avanzados de Machine Learning/Deep Learning y suelen ser herramientas comerciales en Cloud las que proveen estos servicios.

Beneficios del Visual Testing

  • Complementa las herramientas de automatización existentes, integrándose con ellas y en sus procesos de Integración continua (CI/CD). Las distintas herramientas de Visual Testing se utilizarán durante las pruebas automatizadas de Web/Mobile, detectando bugs que los Frameworks actuales como Selenium o Cypress no serían capaces de detectar y que sería bastante completo dado el número de resoluciones, navegadores, etc. No obstante, no son excluyentes entre sí, sino complementarios aumentando la cobertura y la eficacia de nuestra automatización.
  • Verificación de cambios de contenido complejo (gráficos, dashboards, etc.) que para herramientas como Selenium o Cypress sería una actividad muy dificultosa.
  • Aumenta el tiempo de creación y reduce el mantenimiento. Teniendo en cuenta que la verificaciones son muy visuales, este tipo de automatización nos ahorra un gran número de localizadores; usado correctamente, puede aumentar el tiempo de crear scripts de pruebas y reducir el tiempo de mantenimiento.

Flujo de trabajo de las herramientas de Visual Testing

Las herramientas de Visual Testing consisten, en su gran mayoría, en la comparación de una captura de pantalla que cumple el diseño que debería tener (llamada Baseline o imagen base), y posteriormente encontrar fallos comparándola con la versión actual de la aplicación. Podríamos decir que su flujo de trabajo o workflow sería el siguiente:

  1. Tienes una imagen base que cumple el diseño o los requerimientos de una pantalla de tu aplicación (Baseline).
  2. La automatización realizar una captura de pantalla.
  3. Se compara la captura de pantalla con la Baseline.
  4. Si se encuentra diferencias hay que tener en cuenta:
  • Si la captura corresponde a una actual versión de la aplicación que está correcta, entonces se actualiza la Baseline.
  • Si está mal, se reporta un Bug Visual si procede.

No obstante, no todas las herramientas de Visual Testing se basan en capturas de pantalla. Algunas herramientas se basan en verificar un CSS o un archivo de configuración; podríamos decir que en vez de tener una Baseline tendríamos una especificación.

Clasificación de las Herramientas de Visual Testing

Orientadas a código (Open Source & free)

Son, por lo general, librerías o Frameworks donde el proceso de la comparación de imágenes es totalmente dirigido por el código. Aquí tendríamos (aunque existen muchos más): ios-snapshot-test-case (Uber Open Source, XCTest), Needle (Python), Pix-Diff (JS and Protractor), VisualCeption (PHP and CodeCeption) y Specter (Uses a JS DSL).

Ejemplo de Needle:

from needle.cases import NeedleTestCase
 
class BBCNewsTest(NeedleTestCase):
    def test_masthead(self):
        self.driver.get('http://www.bbc.co.uk/news/')
        self.assertScreenshot('#blq-mast', 'bbc-masthead')

Orientadas a configuración (Open Source & free)

Como comentamos anteriormente, no todas las herramientas se basan en capturas. Las herramientas orientadas a configuración se basan en verificar una pantalla del aplicativo contra una especificación que debería de cumplir. En este tipo de herramientas, las más importantes son: dpxdtMake-DepictedCSS CriticGrunt PhotoboxCSS Visual TestSnap And CompareGalen Framework y Automotion.

Ejemplo de Galen Framework con Java + Maven + TestNG:

public class WelcomePageTest extends GalenTestNgTestBase {
 
    @Override
    public WebDriver createDriver(Object[] args) {
        return new FirefoxDriver();
    }
 
    @Test
    public void welcomePage_shouldLookGood_onDesktopDevice() {
        load("http://example.com", 1024, 768);
        checkLayout("/specs/welcomePage.spec", asList("mobile"));
    }
 
}

Orientadas a cloud (comerciales)

Son herramientas, normalmente propietarias o con licencias gratuitas limitadas, donde te ofrecen un API, integración con los principales Frameworks de pruebas automatizadas y una plataforma web para administrar las pruebas. Las principales son: ApplitoolsPercy y Screener.io.

Ejemplo paso a paso de Visual AI usando Java, Selenium y AppliTools Eyes SDK

Applitools es una herramienta web propietaria orientada al Visual Testing que usa algoritmos de Inteligencia Artificial de visión por computador (Visual AI) y con su sede principal en San Mateo, California.

Para tener esta herramienta con las características al 100% necesitamos una licencia. No obstante, podemos registrarnos gratuitamente y con esta cuenta free podríamos comparar 100 interacciones al mes usando su motor de comparación; para evaluar un producto o hacernos una idea de su potencial, es más que suficiente. Teniendo las siguientes características en su versión Free:

  • Eyes SDK. Soporta web, web mobile, mobile y desktop.
  • Eyes SDK UltraFast Grid. Pensado para web responsive.

Escenario para probar con AppliTools

Como web base vamos a usar un dashboard gratuito de Angular material, el cual modificaremos para buscar posteriormente Visual Bugs. La automatización en Selenium será muy simple y solamente navegará a la sección de usuario, pero Applitools guardará captura de ambas páginas (la principal y la de usuario) y evaluará los cambios en posteriores ejecuciones. Para este ejemplo vamos a utilizar Eyes SDK.

El objetivo es ver cómo captura las diferencias en la segunda ejecución donde incluiremos cambios muy difíciles de detectar por la automatización tradicional (o que requerirían como mínimos cálculos o programación más o menos complejos). Los cambios serán:

  • Dashboard principal:
    • El cambio de gráficas
    • Cambio de color
  • Sección de usuario:
    • Cambio del tipo de fuente
    • Desaparición de un icono
    • Desalineación del icono de notificaciones (campanita)

Registrarse en Applitools y obtener el API Key

Para registrarse hay que acceder a https://applitools.com/ y clicar en “Get Started”.

A continuación, rellenar el formulario.

Una vez hemos verificado nuestra cuenta, nos vamos a nuestro perfil y obtenemos la API key como aparece en la siguiente imagen:

Nos aparece una ventana emergente con la API key:

Importante: esta API key será añadida en el código de más abajo con config.setApiKey (“tu API key”).

Diseñar un script

Vamos a utilizar Maven, Java, Selenium y Applitools, por lo tanto necesitaremos las siguientes dependencias en el pom.xml:


       
       
           com.applitools
           eyes-selenium-java3
           3.201.1
       
       
       
           javax.activation
           activation
           1.1.1
       
   
           org.junit.jupiter
           junit-jupiter-engine
           5.8.0-M1
           test
       


La web de ejemplo será cargada desde file:///  en local en la carpeta site, teniendo dos versiones una site/example (la original) y la otra site/example_v2 (la modificada para que detecte visual bugs).

Vamos a crear una clase llamada ExampleAppliToolsWeb donde tendremos dos tests que cargarán dos websites: una la web ubicada en site/examples, donde sus imágenes serán tomadas como Baseline, y otra modificada que nos tendría que reportar fallos en la comparación ubicada en site/examples_v2. Estas pruebas llamaran al método testBase (explicado más adelante) y se tendrá que pasar la resolución del monitor.

@Test
public void test_baseline_1280() {
    testBase("examples", new RectangleSize(1280, 600));
}
 
 
@Test
public void test_visual_Bugs_1280() {
    testBase("examples_v2", new RectangleSize(1280, 600));
}

¡Importante! Para saber rápidamente su resolución ,una vez hayas redimensionado una web a mano, tendrías que lanzar screen.width y screen.height en la consola javascript en Chrome developer tools:

El método testBase ejecutará AppliTools teniendo dos checkpoints: uno con la página de “dashboard” y otra con la página de usuarios (“user page”). El checkpoint tiene esta forma (para más información puedes consultar la documentación de appliTools) cada vez que se llama a este método se  hace una captura y la sube a Applitools para hacer la comparación.

eyes.check(Target.window().fully(false).withName("Dashboard"));

Este punto es bastante importante y, a la selección de Baseline, deberían seguirse una serie de buenas prácticas. Recomiendo leer esta guía de la web de Applitools.

A continuación el código del método testBase que ejecutará un test genérico en AppliTools:

private void testBase(String version,RectangleSize size)  {
        //----------------------------------
        //set local website from project base dir
        String projectBaseDir =  (String) System.getProperties().get("basedir");
        String url =
                    "file:///" + projectBaseDir.replace("\", "/")
                    + "/site/material/"
                    + ""+version
                    +"/dashboard.html";
        //file:///C:/Users/jaime.rodriguez/git/applitools/blog-applitools/site/material/examples/dashboard.html
        System.out.println("projectBaseDir="+projectBaseDir+",url="+url);
        //----------------------------------
        //set chromedriver location ( win )
        System.setProperty("webdriver.chrome.driver", projectBaseDir + "/chromedriver.exe");
        //--------------------------------
        // init chrome driver and AppliTools's eyes
        // Use Chrome browser
        WebDriver driver = new ChromeDriver();
        // Initialize the Runner for your test.
        EyesRunner runner = new ClassicRunner();
        // Initialize the eyes SDK
        Eyes eyes = new Eyes(runner);
        //---------------------------------
        // Setup Eyes
        // Initialize the eyes configuration.
        Configuration config = new Configuration();
        // You can get your api key from the Applitools dashboard
        config.setApiKey("PON TU API KEY AQUI");
        // set new batch
        config.setBatch(new BatchInfo("Blog SDOS Applitools + Selenium"));
        // set the configuration to eyes
        eyes.setConfiguration(config);
        //---------------------------------
        // Automation
        try {
            eyes.open(driver, "Blog SDOS Applitools + Selenium", "My Smoke Test - 4", size );
            driver.get( url);          
            // Visual checkpoint #1 - Check the login page. using the fluent API
            // https://applitools.com/docs/topics/sdk/the-eyes-sdk-check-fluent-api.html?Highlight=fluent%20api
            eyes.check(Target.window().fully(false).withName("Dashboard"));
            // This will create a test with two test steps.
            driver.findElement(By.xpath(".//a[@href='./user.html']")).click();
            // Visual checkpoint #2 - Check the app page.
            eyes.check(Target.window().fully(false).withName("User Page"));
            // End the test.
        }finally {
            eyes.closeAsync();
            driver.quit();
            TestResultsSummary allTestResults = runner.getAllTestResults();
            System.out.println(allTestResults);
        }
    }

Lanzar el script contra una Web y ver los resultados en AppliTools

El primer test se ejecutaría mediante un terminal con el siguiente comando Maven:

$> mvn clean test -Dtest=ExampleAppliToolsWeb#test_baseline_1280

Y tendremos como resultado:

INFORMACIÓN: Detected dialect: W3C
result summary {
    all results=
        TestResultContainer{
 testResults=New test [ steps: 2, test name: My Smoke Test - 4, matches: 0, mismatches:0, missing: 0] , URL: https://eyes.applitools.com/app/batches*****?accountId=***
 exception = null}
    passed=1
    unresolved=0
    failed=0
    exceptions=0
    mismatches=0
    missing=0
    matches=0
}
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 52.998 s - in com.applitools.quickstarts.ExampleAppliToolsWeb

Obtenemos la ejecución “Blog SDOS Applitools + Selenium”:

Estas dos imágenes serían la Baseline (a no ser que le indiquemos lo contrario) donde se pondría la mano de OK. Si accedemos a las imágenes del Dashboard:

Y la sección de usuario:

Relanzar el script contra la Web cambiada.y visualizar los cambios

Para lanzar la versión de la web que tiene cambios hay que lanzar la siguiente prueba desde un terminal:

$> mvn clean test -Dtest=ExampleAppliToolsWeb#test_visual_Bugs_1280

Y obtenemos como resultado:

com.applitools.quickstarts.ExampleAppliToolsWeb
[ERROR] com.applitools.quickstarts.ExampleAppliToolsWeb.test_visual_Bugs_1280  Time elapsed: 52.369 s  <<< ERROR!
java.lang.Error: com.applitools.eyes.exceptions.DiffsFoundException: Test 'My Smoke Test - 4' of 'Blog SDOS Applitools + Selenium' detected differences! See details at: https://eyes.applitools.com/app/batches/*****5?accountId=****
    [...]
Caused by: com.applitools.eyes.exceptions.DiffsFoundException: Test 'My Smoke Test - 4' of 'Blog SDOS Applitools + Selenium' detected differences! See details at: https://eyes.applitools.com/app/batches/******?accountId=****
    [...]
[INFO]
[INFO] Results:
[INFO]
[ERROR] Errors:
[ERROR]   ExampleAppliToolsWeb.test_visual_Bugs_1280:92->testBase:78 »  com.applitools.e...
[INFO]
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

Si nos conectamos a Applitools podemos observar cómo la ejecución “Blog SDOS Applitools + Selenium” se ha ejecutado y podemos ver las capturas de pantalla.

Página por página nos muestra las diferencias, remarcándolas de otro color, como podemos ver en la siguiente imagen en la que se detecta en el dashboard el cambio de color en la campana de notificaciones y cambios en las gráficas. Esto último es difícil de detectar mediante automatización tradicional, siendo fuente de un bug funcional. No obstante, hay que tener cuidado porque esto es un ejemplo y este tipo de herramientas no está pensada para este fin. Lo más normal es diseñarlas para objetivos puramente visuales.

Podemos observar cómo en el test estaría en un estado de ‘Unresolved‘. Este no pasa a ‘Failed‘ o ‘Passed‘ directamente hasta que un humano verifique si es un bug o forma parte de una nueva Baseline. Esto se hace navegando imagen por imagen y marcándolas como OK o como KO clicando en los iconos:

En la página de usuario, o user profile, se observa que ha cambiado el tipo de fuente en la descripción del CEO y, al quitar el icono de settings, se ha desmaquetado el icono de notificaciones. Esto, en un caso real, habría que revisarlo y se podría reportar como un visual bug.

Conclusiones

  • El Visual Testing es una buena estrategia para reforzar nuestros planes de pruebas verificando más allá de los requisitos funcionales, no solo dando un plus de calidad al producto sino porque, dado la cantidad de dispositivos y navegadores, se hace necesario este tipo de herramientas para optimizar la búsquedas de fallos visuales a distintas resoluciones cuando se publica una nueva versión de la aplicación, reforzando los planes de prueba de regresión.
  • Las herramientas de Visual Testing automatizado pueden complementar la automatización con Frameworks como Selenium, Appium, etc. y siendo usadas correctamente pueden incluso aumentar la productividad y fiabilidad de estas en ciertos escenarios.
  • Los enfoques actuales tienden a que las herramientas de Machine/Deep Learning sean una evolución frente a las tradiciones de algoritmos de píxeles y aumenten su fiabilidad. Sin embargo, son comerciales, lo que provoca un sobrecoste en el proyecto.
  • Si no se elige una estrategia adecuada, este tipo de pruebas tiende a ser poco sostenibles y la automatización pueden ser, además, poco exacta dando falsos negativos y positivos.

Y hasta aquí nuestro resumen de Applitools. En próximas entradas del blog te contaremos otros aspectos del Visual Testing que seguro que te serán de gran utilidad.

Jaime Rodríguez,
QA Service Manager