Pruebas de interfaz de usuario en .Net (y 2)

Después de una primera parte introductoria, en este artículo vamos a analizar un ejemplo de pruebas de interfaz de usuario con UI Automation.

En un principio pensé en programar una sencilla aplicación WPF para nuestro banco de pruebas, pero he pensado en algo mejor: vamos a hacer pruebas sobre una aplicación descargada de la Microsoft Store. Es divertido descubrir el control que podemos llegar a tener sobre nuestras aplicaciones favoritas. Nuestro ejemplo va a consistir en probar el proceso de login de Wunderlist, un popular gestor de tareas, por lo que si no lo tienes instalado ya, puedes descargarlo de forma gratuita desde aquí.

El código del ejemplo que vamos a estudiar puedes descargarlo desde GitHub. Sin embargo, el propósito de este artículo no es analizar línea por línea el código fuente del ejemplo, sino más bien complementar la información que puede extraerse de los comentarios (numerosos y descriptivos) y el análisis del código. Mi intención es que aquellos no tan interesados en los detalles técnicos puedan entender el proceso de elaboración de las pruebas de interfaz de usuario desde una perspectiva más general, sin dejar de incluir enlaces a documentación online para aquellos que deseen profundizar.

Los nodos

El escritorio de Windows está estructurado como un árbol de elementos gráficos donde el nodo raíz es “Desktop”. De él cuelgan todos los nodos que representan los controles y elementos visuales (y algunos que no son visuales sino lógicos). Por ejemplo, del nodo “Desktop” cuelga un nodo de tipo panel, y de él a su vez el nodo que representa el botón de inicio, de nombre “Start”. Los nodos van a ser el centro de las pruebas ya que a través de ellos vamos a interactuar con cualquier aplicación abierta con elementos visuales, y también con el propio sistema operativo.

Con este propósito necesitamos una herramienta capaz de mostrarnos la jerarquía completa de los nodos del escritorio, como Inspect.  Inspect viene instalado con Windows Software Development Kit (SDK) y está localizado en la carpeta “\bin\<version>\<platform>” del SDK, que en mi equipo es “C:\Program Files (x86)\Windows Kits\10\bin\x86”. Prueba a ejecutarlo y a navegar por los nodos, prestando especial atención a la lista de propiedades de cada uno. Cuando preguntemos al sistema por un nodo, lo vamos a identificar por estas propiedades.

Inspect

Las pruebas

Para nuestras pruebas de interfaz de usuario vamos a hacer un pequeño esquema con los nodos visuales de la aplicación a estudio, Wunderlist. En este esquema hay que incluir la ruta hacia aquellos controles que vamos a usar, en nuestro caso los botones de inicio de sesión, y las entradas correspondientes al usuario y la contraseña. ¿Qué propiedades van a identificar un nodo? Las principales que yo uso son “Name”, “ClassName” y “AutomationId”, pero depende de cada caso. Cada nodo puede representar objetos muy diferentes y no todas las propiedades están disponibles para todos los nodos.

esquema

Esta es la ventana representada en el esquema de nodos, a la izquierda en su estado inicial y a la derecha tras pulsar el botón “Iniciar Sesión”.

Wunderlist login 1Wunderlist login 2

Las pruebas de interfaz de usuario consisten en recuperar los nodos que nos interesan, inspeccionar sus propiedades y actuar sobre sus patrones: “InvokePattern” para pulsar un botón, “ValuePattern” para rellenar una caja de texto, “SelectionItemPattern” para seleccionar un elemento de una lista deplegable… y así. Para una introducción sobre los patrones de UI Automation, puedes visitar este enlace. Para comprender el proceso de recuperación de nodos y de operación sobre patrones, puedes examinar la clase “ViewTree.cs” del proyecto UITestSample.

Verificación

Pero a nuestro plato aún le falta un ingrediente: verificar el éxito o fracaso de la prueba. ¿Cómo? Detectando cambios en la estructura de la aplicación. El usuario de una aplicación recibe feedback visual de sus acciones, tanto de las correctas como de las incorrectas. Si introducimos mal el correo electrónico, aparecerá un mensaje de alerta para que reintroduzcamos bien el campo. Y si todo ha ido bien, la aplicación cargará correctamente.

Ahora viene una parte delicada del trabajo: elegir qué evento nos interesa verificar. Esto dependerá de cada caso, ya que unas veces se abrirá una ventana y será interesante capturar el evento “WindowPattern.WindowOpenedEvent”, y otras se modificará la estructura de nodos (ocultándose algunos y apareciendo otros) de manera que el aspecto visual de la aplicación cambiará sensiblemente.

Al hacer login en Wunderlist no se cierra ni se abre ninguna ventana, sino que la ventana principal sufre una metamorfosis. Entonces el caso que nos ocupa corresponde al de cambio de estructura. Si comprobamos el código de la clase LoginUITest dentro del proyecto UITestSample, veremos que registramos un callback con el método “Automation.AddStructureChangedEventHandler”. Para saber más sobre suscripción de eventos con UI Automation, puedes visitar este enlace.

OK

Recomendaciones finales

Este artículo se queda corto para hablar de UI Automation y de pruebas de interfaz, pero es un punto de partida para aquél que quiera evaluar la inclusión de esta tecnología en su caja de herramientas, o también que quiera recomendar el artículo a alguien que pueda necesitar algo parecido. He dejado suficientes pistas en el código para quien quiera encontrarlas.

Pero no quiero terminar este artículo sin dejar un par de ideas:

  • No sabemos de antemano qué lógica encierra cada control. Los hay muy sencillos, pero es más habitual encontrar herencias complejas que encapsulan validaciones internas y comportamientos no esperados. Hay que estudiar cada control de forma individual. Algunos pueden dar mucho trabajo.
  • En ocasiones los patrones disponibles para un nodo no ayudan. Ése es el momento de acudir a la simulación de eventos de teclado y ratón con librerías externas, como InputSimulator de Michael Noonan, descargable desde GitHub o como NuGet.
  • Si has abierto el código de ejemplo, te habrás dado cuenta de que en la clase LoginUITest hay métodos nombrados como “GetAnchor()”. Estos métodos sirven para recorrer el camino desde el nodo raíz hasta ciertos nodos que yo denomino “puntos de anclaje”. Estos son nodos que deben revisitarse para acceder a ciertas sub-ramas. Pero también hay otro motivo: los nodos son referencias con una validez limitada. En ocasiones se tiene una referencia a un nodo y, de pronto, deja de funcionar. Esto es debido a que el árbol de nodos cambia constantemente en respuesta a eventos no siempre obvios.

Pedro Pinto SogetiPedro Pinto

Senior Developer | Soluciones Microsoft | SOGETI España

Autor: ITblogsogeti

Sogeti es una compañía tecnológica perteneciente al Grupo Capgemini y especialista en: Testing y Calidad de Software; Soluciones Microsoft y High Tech Consulting. En Sogeti entendemos la importancia de obtener el máximo valor empresarial de sus sistemas de IT, por ello somos líderes mundiales en Testing & QA.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s