Table of Contents
Escribir test de interfaz de usuario es siempre un poco complicado, y muchos desarrolladores acaban por dejar vistas sin testear o dedicando mucho tiempo y esfuerzo en la elaboración de test. Apple dispone de su propio soporte nativo para testing de UI, pero no da soporte para hacer view-based testing. Esta carencia de funcionalidad hace que mucha gente opte por no escribir test dada su dificultad. Por eso en Apiumhub hemos decidido escribir un articulo sobre iOS Snapshot tests.
iOS Snapshot tests
View-based testing
View-based testing significa verificar que lo que el usuario ve es lo que queremos nosotros como desarrolladores que el usuario vea. Gracias a este testing podemos garantizar que en diferentes estados o versiones de nuestras vistas se muestran como deberían.
iOS Snapshot Tests. ¿Como funcionan?
El snapshot test toma una captura de una UIView or CALayer i usa el método renderInContext el cual realiza una captura de la vista y la compara con la imagen de referencia guardada en nuestro repositorio. El test falla si ambas imágenes no coinciden y entrega una tercera captura mostrando las diferencias.
Configuración
La librería fue creada por Facebook (FBSnapshotTestCase) y ahora se ha renombrado a iOSSnapshotTestCase y es mantenida por uber.
El primer paso, como explican en su página de Github, es añadir la librería a nuestro Podfile.
Seguidamente editamos el esquema de nuestro target para añadir el directorio donde se guardarán nuestras capturas de referencia. Para ello añadimos una variable de entorno con la clave FB_REFERENCE_IMAGE_DIR.
Opcionalmente también podemos añadir la clave IMAGE_DIFF_DIR para indicar el directorio donde se guardarán las capturas diferenciales que se generarán en caso de que nuestros test fallen.
Implementación
Para ver la implementación vamos a testear un simple viewcontroller que cambiará de aspecto visual dependiendo de un estado.
La vista con los dos estados:
Configuramos nuestra clase de test haciendo que esta sea una subclase de FBSnapshotTestCase en lugar de XCTestCase.
Definimos nuestros tests instanciando el ViewController, asignando el estado y llamando al método FBSnapshotVerifyView.
Primero de todo debemos de ejecutar los test con el recordMode activado para que guarde las imágenes de referencia. Para ello introducimos dentro del método de setUp() recordMode = true.
Al ejecutar los test con recordMode activado, saldrán Fail. Es normal debido a que no tiene aún otra imágen con la que hacer la comparación.
Seguidamente comentamos o eliminamos la línea de recordMode para lanzar otra vez los test y ver que pasan.
A partir de ahora si el aspecto visual de la vista cambia como no debería, nuestros test nos notificarán.
Por ejemplo si cambiamos sin querer la dimensión de los iconos el test nos generará una imagen diferencial con los cambios.
He aumentado para el test 20px el tamaño del icono, y en la imágen diferencial se puede ver reflejado el cambio.
Ejecutar vistas de manera aislada
Gracias al snapshot testing y a tener las vistas desacopladas podemos instanciar y ejecutar en el simulador un ViewController determinado. Muy útil en para acelerar el proceso de creación de las vistas y reduciendo así el tiempo de desarrollo.
En nuestro didFinishLaunchingWithOptions comprobamos si estamos corriendo test y en ese caso asignamos al rootViewController un UIViewController plano y vacío.
En nuestra clase de Test usamos un XCTWaiter con un timeout elevado y asignamos al rootViewController el controller a ejecutar.
Finalmente en el test llamamos al método debugViewController.
De este modo podemos ejecutar la típica vista que está dentro de un largo flow de pantallas de nuestra app de manera sencilla.
Suscríbete a nuestro newsletter para estar al día de desarrollo de aplicaciónes moviles e iOS Snapshot tests en concreto!
Si este artículo sobre iOS Snapshot tests te gustó, te puede interesar:
Tendencias en aplicaciónes móviles
Debugging con Charles Proxy en Android emulator
Integración Continua en iOS usando Fastlane y Jenkins
Cornerjob – iOS objective-C app un caso de exito
Author
-
More than 10 years on software development field, and working on mobile development since 2013. Experience creating apps from scratch and working on big applications with several dependencies. Used to work with the latest technologies and take care of architectural decisions. Able to lead small iOs teams, always from the tech side.
Ver todas las entradas