La automatización de las pruebas de interfaz de usuario en iOS se ha convertido en algo tan fácil como escribir pruebas unitarias desde que Apple introdujo el framework XCUI. En este post, voy a hablar de cómo XCUI, junto con el diseño en capas, puede ayudar a automatizar fácilmente las aplicaciones, especialmente aquellas con múltiples elementos de interfaz de usuario personalizados. Una de esas aplicaciones en las que utilizamos esto ampliamente es VMware Boxer, una aplicación empresarial de VMware que agrega tres funciones importantes: correo electrónico, calendario y contactos. VMware Boxer utiliza múltiples tipos de elementos de UI, desde UITableView nativo hasta elementos visuales altamente personalizados.
Se asume que los lectores tienen un conocimiento básico de Xcode, Objective C, Swift, el marco XCUI y el ecosistema de desarrollo de Apple en general. Si usted es nuevo en XCUI, primero debe comenzar aquí.
Como cualquier otro proyecto de automatización de la interfaz de usuario, nuestro equipo comenzó con una pregunta sobre qué marco de automatización a utilizar. Habíamos estado usando SeeTest. Sin embargo, vimos esto como una oportunidad para revisar nuestra estrategia de automatización dada la nueva y compleja funcionalidad añadida en VMware Boxer, el número de productos en el ecosistema de VMware y las pruebas de integración a través de estos productos. A continuación, las opciones que consideramos-
1. Continuar con SeeTest
2. Earl Grey
3. XCUI
Si bien SeeTest tenía la capacidad de manejar nuestras necesidades inmediatas de automatización, había un desafío independiente que enfrentar. Nos exigía adoptar una nueva pila tecnológica. Esto requeriría una formación adicional para los desarrolladores de iOS y expertos dedicados a mantener el sistema de automatización.
¿Qué pasa con Appium? No consideramos Appium por las mismas razones mencionadas anteriormente para SeeTest. Appium es una buena opción si tuviéramos aplicaciones híbridas o un código compartido importante entre Android e iOS.
Earl Grey 1 era una posible opción, dado que nos permitía permanecer en Xcode y en las herramientas de desarrollo de Apple y estaba basado en XCTest. La automatización de Earl Grey 1, sin embargo, se ejecuta en el mismo proceso que la aplicación bajo prueba. Por otro lado, la automatización basada en el marco XCUI de Apple se ejecuta en un proceso distinto al de la aplicación bajo prueba. Esto es preferible ya que la aplicación bajo prueba debe ser nada más que una caja negra para la entidad (un proceso de automatización o un usuario final) que está probando su UI.
Tener el proceso de automatización (que está probando) aislado de la aplicación real bajo prueba. La aplicación bajo prueba debe ser nada más que una caja negra para el proceso de automatización.
Cualquier herramienta nueva en el ecosistema de Apple que no esté alineada con el enfoque de Apple (por ejemplo, Earl Grey 1) puede fallar sin previo aviso. Tal enfoque puede requerir un gran esfuerzo de mantenimiento para seguir trabajando con ofertas más nuevas o futuras de Apple.
El Earl Grey 2 añadió la capacidad de interactuar con XCUI. Fue un intento de alinearse con XCUI pero tenía estos problemas conocidos.
Al final, XCUI fue la opción preferida. Con esto, un desarrollador tendrá más control sobre la automatización y será el beneficiario inmediato de cualquier innovación en el ecosistema de Apple.
Aplicación bajo prueba y módulo de automatización XCUI
Antes de entrar en detalles, es importante reiterar que el módulo de automatización que utiliza XCUI se ejecuta como un proceso independiente de la aplicación que está bajo prueba. Para empezar, añadimos un nuevo módulo al que nos referiremos a partir de ahora como Módulo de Automatización (AM). AM es un espacio de trabajo que contiene una colección de clases y estructuras de datos utilizadas para la automatización de VMware Boxer utilizando XCUI.
Identificadores de accesibilidad
Es importante que la aplicación se desarrolle teniendo en cuenta su testabilidad. Una de las responsabilidades del desarrollador es asegurarse de que cada elemento de la interfaz de usuario que se expone al usuario final tiene el identificador de accesibilidad establecido durante el desarrollo. El identificador de accesibilidad es el enlace entre la aplicación bajo prueba y el proceso de automatización XCUI.
El identificador de accesibilidad es el enlace entre la aplicación bajo prueba y el proceso de automatización XCUI.
Patrón de diseño
Como se ha mencionado anteriormente, VMware Boxer es una aplicación enorme. La elección del patrón de diseño a utilizar se llegó teniendo en cuenta que las pruebas deben ser fáciles de implementar, fáciles de mantener, reutilizables, robustas y escalables. El contenido siguiente explica las capas de la arquitectura del módulo de automatización XCUI para VMware Boxer:
La siguiente figura muestra los bloques de construcción básicos:
Clases de prueba
Esta es la capa que tiene las clases que tienen los métodos de prueba. La intención de esta capa es que las pruebas consten de un código mínimo que diga sólo lo que se está probando. Además, el desarrollador que implementa las pruebas sólo necesita pensar en el flujo de la aplicación de alto nivel requerido para probar lo que se está probando. El resto de la complejidad (por ejemplo, cómo navegar hasta la interfaz de usuario en la que se puede realizar la prueba deseada) debe abstraerse en capas reutilizables. Refiérase a la imagen de abajo que muestra un ejemplo de método de prueba que explica la intención anterior – el código prueba si una UI de Configuración puede ayudar a habilitar/deshabilitar una característica o si tiene controles de conmutación requeridos.
Así, el desarrollador que está escribiendo las pruebas podría escribir un código tan simple como el pseudocódigo. Mientras tanto, está claro que alguna lógica debe ser invocada desde la siguiente capa (Flows : se explica en la siguiente sección).
Clases de Flows
Los Flows representan una colección de clases que proporcionan funcionalidades requeridas para varias clases de Tests. Las funcionalidades podrían incluir la configuración de la aplicación antes de ejecutar el caso de prueba real o la navegación a una determinada parte de la aplicación bajo prueba. La mayoría de estas funcionalidades son reutilizables y se requieren en múltiples pruebas. Navegamos a una pantalla de configuración del Controlador de Características.
Por lo tanto, las clases de Flujo serían invocadas desde las Pruebas e implementarían flujos como «Navegar a la Configuración» o «Navegar a la Configuración del Controlador de Características».
Clases de Pantallas
Las Pantallas son clases que tienen un mapeo uno a uno con los respectivos Controladores de Vistas. Un Controlador de Vista puede ser, a alto nivel, visto como una clase que tiene (en la vista de respaldo) UIControls y métodos que responden a la interacción del usuario con esos UIControls. Una clase Screen es simplemente un mapeo proxy del View Controller. La figura siguiente muestra este mapeo. Hay una celda Initial View en la UI y cuando el usuario toca en esta celda, el usuario puede seleccionar lo que debe ser marcado como la vista inicial para la aplicación. La siguiente figura muestra cómo una clase de pantalla se implementa para asignar el requisito anterior.
El pseudocódigo para esta clase de pantalla se vería como –
// The class models the SettingFormViewController for XCUI tests.public class SettingsFormScreen {
private static let navBarId = "Boxer.Settings.NavigationBar"
private lazy var featureControllerCell = boxerApp.application.tables.cells public func navigateToFeatureController() -> Bool {
return // tap on Cell with featureControllerCellId
}
}class AccessibilityIdentifiers: NSObject {// MARK: Settings Screenstatic let featureControllerCellId = "Boxer.Settings.FeatureControllerCell"
}
¿Qué es boxerApp en el código anterior? En el código anterior boxerApp representa una unidad que es una instancia de la clase BoxerApp que encapsula la aplicación bajo prueba y sus pantallas. Esto se explica en la siguiente sección.
El código anterior modela el SettingFormViewController de VMware Boxer. La convención utilizada para nombrar la clase es que el nombre se deriva del nombre del controlador de vista sustituyendo el sufijo ViewController por Screen. También hay que tener en cuenta la clase de conveniencia que tiene identificadores de accesibilidad.
El identificador de accesibilidad es el enlace común entre la aplicación bajo prueba y el proceso de automatización XCUI.
Poniéndolo todo junto: Módulo de automatización XCUI de VMware Boxer
El módulo UITest prueba la aplicación en ejecución. Es importante que el modelo de aplicación se diseñe de forma que una instancia de la app bajo prueba sea una sola unidad. Esto significa que la aplicación bajo prueba debe ser vista como una colección de clases de pantallas que participan en los flujos de negocio (colección de clases de flujo)que se invocan desde las pruebas (colección de clases)basadas en el requisito de la prueba. Cada unidad de aplicación debe tener exactamente una instancia de cada clase de pantalla que corresponde a un controlador de vista.
¿Cómo lograr esto?
Un conjunto de pruebas XCUITest puede lograr esto encapsulando la instancia de la aplicación bajo prueba (XCUIApplication) en una unidad, por ejemplo, la clase BoxerApp que tiene una aplicación miembro y tiene todas las pantallas para esa aplicación. La figura siguiente explica esta encapsulación
Por lo tanto, antes de que la suite XCUITest se inicie, lo primero que haría es crear una instancia del módulo BoxerApp utilizando el identificador del paquete de la aplicación bajo prueba. La figura siguiente lo explica
Esta instancia de BoxerApp (la unidad que encapsula el XCUIApplication y las pantallas) es entonces pasada por el Tests::testMethod a Flows::flowMethod como primer parámetro.
El Flows::flowMethod llama a su vez a Screen::screenMethod y pasa BoxerApp si es necesario.
Finalmente la interacción con la UI de la aplicación ocurre a través de Screen::screenMethod.
La figura siguiente muestra el diseño anterior.
Conclusión
Escribir pruebas XCUI puede ser engorroso e inmanejable si no se hace con un plan. Espero que este post proporcione indicaciones útiles sobre cómo pensar en la estructuración de su proyecto de automatización de una manera modular, limpia y en capas.
¿Qué es lo siguiente?
Voy a cubrir estos temas en la serie de historias que estoy planeando:
XCUI : Parte 2 -Interactuar con las aplicaciones nativas de una manera limpia
XCUI : Parte 3 -Cómo el tiempo de ejecución de XCUI puede interactuar con la aplicación bajo prueba de una manera limpia.
XCUI : Parte 4 -Manejando las Alertas del Sistema.
XCUI : Parte 5 -Observando el Progreso de las Pruebas y accediendo a informes y capturando Pantallas.