Pruebas de UI: Implementación y Validación de Flujos de Navegación
Clase 13 de 15 • Curso de Swift Unit Testing
Resumen
La automatización de pruebas de interfaz de usuario es fundamental para garantizar que nuestras aplicaciones funcionen correctamente desde la perspectiva del usuario. Dominar los flujos de navegación en pruebas UI permite validar no solo elementos estáticos, sino también interacciones complejas entre pantallas, lo que resulta en aplicaciones más robustas y confiables.
¿Cómo implementar pruebas para flujos de navegación entre pantallas?
Cuando desarrollamos aplicaciones, no basta con probar elementos individuales en una pantalla. Es crucial verificar que los flujos de navegación funcionen correctamente, como abrir formularios o navegar a detalles de registros. Estas pruebas garantizan que el usuario pueda moverse por la aplicación sin problemas.
Para implementar estas pruebas, necesitamos:
- Identificar los elementos UI que inician la navegación
- Validar que los elementos de la pantalla destino aparezcan correctamente
- Manejar adecuadamente las transiciones entre pantallas
¿Cómo probar la apertura de un formulario?
Para probar el flujo de abrir un formulario para agregar un nuevo registro, podemos implementar el siguiente test:
func testAddRecord() {
// Descripción: Muestra el formulario de agregar un nuevo registro
// Validar existencia del botón
XCTAssertTrue(addRecordButton.exists)
// Interactuar con el botón
addRecordButton.tap()
// Validar que aparezca el formulario
let newRecordSheet = app.staticText["form_record_title"]
XCTAssertTrue(newRecordSheet.waitForExistence(timeout: 3))
}
En este test, primero verificamos que el botón para agregar un registro exista en la pantalla principal. Luego, simulamos un tap en ese botón y finalmente validamos que el título del formulario aparezca en la nueva pantalla.
Es importante notar que utilizamos waitForExistence(timeout:)
en lugar de simplemente exists
. Esto es crucial porque hay una transición entre pantallas y necesitamos darle tiempo al sistema para mostrar la nueva vista.
¿Cómo probar la navegación al detalle de un registro?
Para probar la navegación al detalle de un registro existente, necesitamos un enfoque diferente, especialmente cuando los elementos son dinámicos:
func testNavigateToRecordDetail() {
// Buscar el primer registro usando un predicado
let firstRecord = app.buttons.matching(NSPredicate(format: "identifier BEGINSWITH 'record_'")).firstMatch
// Validar que exista al menos un registro
XCTAssertTrue(firstRecord.exists)
// Navegar al detalle
firstRecord.tap()
// Validar que se muestre la pantalla de detalle
let deleteButton = app.buttons["delete_button"]
XCTAssertTrue(deleteButton.waitForExistence(timeout: 3))
}
En este caso, utilizamos un predicado para encontrar elementos cuyo identificador comience con "record_", ya que nuestros registros tienen identificadores dinámicos con ese prefijo. Una vez encontrado el primer registro, verificamos su existencia, simulamos un tap y validamos que aparezca un elemento característico de la pantalla de detalle.
¿Por qué es importante usar datos de prueba controlados?
Cuando realizamos pruebas de UI, es fundamental trabajar con datos predecibles. Por eso, es recomendable usar datos mock o de prueba cuando ejecutamos tests de interfaz:
- Garantiza consistencia: Los tests siempre se ejecutan con los mismos datos
- Evita dependencias externas: No dependemos de servicios o bases de datos reales
- Facilita la validación: Sabemos exactamente qué elementos deben aparecer
En nuestro caso, es crucial tener registros predefinidos para poder probar la navegación al detalle. Sin estos datos controlados, nuestras pruebas podrían fallar simplemente porque no hay registros disponibles.
¿Cómo validar elementos en pantallas después de una transición?
Cuando navegamos entre pantallas, debemos tener en cuenta que hay un tiempo de transición. Por eso, en lugar de verificar inmediatamente la existencia de elementos, debemos:
- Utilizar
waitForExistence(timeout:)
con un tiempo razonable (2-3 segundos) - Identificar elementos clave que confirmen que estamos en la pantalla correcta
- Validar solo los elementos necesarios para confirmar la navegación exitosa
// Incorrecto
XCTAssertTrue(detailView.exists)
// Correcto
XCTAssertTrue(detailView.waitForExistence(timeout: 3))
Este enfoque hace que nuestras pruebas sean más robustas frente a variaciones en el tiempo de carga o transición, evitando falsos negativos.
Las pruebas de UI para flujos de navegación son esenciales para garantizar una experiencia de usuario fluida. Implementarlas correctamente requiere entender cómo manejar transiciones, elementos dinámicos y estados de la aplicación. Te animo a que implementes pruebas para las demás vistas de tu aplicación siguiendo estos principios y compartas tus experiencias en los comentarios.