Fundamentos del Testing en iOS
El testing de iOS requiere entender el ecosistema estrictamente controlado de Apple. A diferencia de Android donde los fabricantes pueden modificar el OS, cada dispositivo iOS ejecuta el sistema operativo sin modificar de Apple. Esta consistencia simplifica algunos aspectos pero introduce desafios unicos.
Ciclo de Vida de Apps iOS
Entender el ciclo de vida es critico para testers moviles porque muchos bugs ocurren durante las transiciones de estado.
Estados de la App
No Ejecutando → Inactiva → Activa → Segundo Plano → Suspendida → Terminada
| Estado | Descripcion | Foco de Testing |
|---|---|---|
| No Ejecutando | App no lanzada o terminada | Rendimiento de inicio en frio |
| Inactiva | En primer plano pero sin recibir eventos | Manejo de interrupciones |
| Activa | En primer plano recibiendo eventos | Funcionalidad normal |
| Segundo Plano | Ejecutando codigo pero no visible | Completar tareas de fondo |
| Suspendida | En memoria pero sin ejecutar codigo | Restauracion de estado |
| Terminada | Removida de memoria | Persistencia de datos |
Escenarios Criticos de Testing
Inicio en frio vs inicio caliente: Mide el lanzamiento desde estado terminado (frio) versus suspendido (caliente). Los usuarios notan si el inicio en frio toma mas de 2 segundos.
Interrupciones: Prueba que sucede cuando:
- Llega una llamada durante una operacion critica
- Se activa Siri
- Aparece alerta de bateria baja
- Se dispara un timer o alarma
- Se abre el Centro de Control
Segundo plano a primer plano: Despues de 30+ minutos en segundo plano, se restaura correctamente? Verifica:
- Tokens de autenticacion expirados
- Datos obsoletos en pantalla
- Entrada de formulario perdida
- Conexiones WebSocket rotas
Presion de memoria: iOS puede terminar apps suspendidas en cualquier momento. Prueba la restauracion de estado despues de que el sistema mata la app.
Herramientas de Testing en Xcode
XCUITest
XCUITest es el framework nativo de testing de UI de Apple. Interactua con la app a traves del sistema de accesibilidad.
// Ejemplo de XCUITest
func testLoginFlow() {
let app = XCUIApplication()
app.launch()
let emailField = app.textFields["Email"]
emailField.tap()
emailField.typeText("user@example.com")
let passwordField = app.secureTextFields["Password"]
passwordField.tap()
passwordField.typeText("password123")
app.buttons["Sign In"].tap()
XCTAssertTrue(app.staticTexts["Welcome"].waitForExistence(timeout: 5))
}
Xcode Instruments
Instruments es el toolkit de profiling incluido con Xcode:
| Instrumento | Proposito | Cuando Usar |
|---|---|---|
| Time Profiler | Analisis de uso de CPU | App se siente lenta |
| Allocations | Rastreo de uso de memoria | Alto consumo de memoria |
| Leaks | Deteccion de fugas de memoria | La memoria crece con el tiempo |
| Energy Log | Consumo de bateria | Drenaje de bateria en segundo plano |
| Network | Profiling de requests de red | Carga lenta de datos |
Sistema de Permisos de iOS
iOS tiene un modelo estricto de permisos. Las apps deben solicitar permiso para recursos sensibles.
Permisos a Probar
| Permiso | Primera Solicitud | Despues de Denegacion | Metodo de Reset |
|---|---|---|---|
| Camara | Dialogo del sistema | Debe ir a Configuracion | Configuracion > Privacidad > Camara |
| Ubicacion | 3 opciones: Una vez, Al usar, Siempre | Solo Configuracion | Configuracion > Privacidad > Ubicacion |
| Notificaciones | Dialogo del sistema | Solo Configuracion | Configuracion > Notificaciones |
| Fotos | Dialogo con acceso limitado/completo | Solo Configuracion | Configuracion > Privacidad > Fotos |
Checklist de Testing de Permisos
- Primera solicitud muestra dialogo correcto
- App maneja denegacion graciosamente (sin crash, mensaje util)
- App funciona con acceso limitado a fotos (iOS 14+)
- Permiso de ubicacion “Al usar” vs “Siempre” se comporta diferente
- Revocar permiso en Configuracion no causa crash
- App Tracking Transparency (iOS 14.5+) aparece antes de cualquier rastreo
Preparacion para Revision del App Store
Apple revisa cada envio de app. Razones comunes de rechazo y como probar:
Top 5 Razones de Rechazo
- Bugs y crashes (mas comun) — Prueba todos los flujos en la version minima soportada de iOS
- Links rotos y contenido placeholder — Verifica todas las URLs en la app
- Metadata incompleta — Screenshots deben coincidir con UI actual
- Problemas de rendimiento — El lanzamiento debe completarse en tiempo razonable
- Violaciones de guias de diseno — Debe usar patrones de navegacion estandar de iOS
Checklist Pre-Envio
□ Probado en version minima soportada de iOS
□ Probado en ultima version de iOS
□ Todos los dialogos de permisos probados
□ Dark Mode probado en todas las pantallas
□ Dynamic Type probado (tamanos mas grande y mas pequeno)
□ Navegacion basica con VoiceOver funciona
□ Sin crashes en logs de Xcode Organizer
□ Todos los links funcionales
□ Privacy manifest actualizado (iOS 17+)
□ Screenshots coinciden con UI actual
Ejercicio: Caza de Bugs iOS
Escenario: Estas probando una app de pedidos de comida en iOS preparandose para su primer envio al App Store.
Identifica bugs potenciales:
- Usuario agrega items al carrito, recibe una llamada, regresa a la app 5 minutos despues
- Usuario otorga permiso de ubicacion como “Al usar la app” pero la app necesita ubicacion para rastreo de entrega en segundo plano
- Usuario tiene Dynamic Type en el tamano mas grande de accesibilidad
Solucion
Restauracion de estado: Los datos del carrito podrian perderse si la app fue suspendida y terminada. Verificar: items del carrito presentes, precios actuales, timers restaurados correctamente.
Discrepancia de permiso de ubicacion: Con permiso “Al usar”, la app pierde acceso a ubicacion en segundo plano. El rastreo de entrega fallara. La app debe solicitar “Siempre” o explicar por que lo necesita.
Overflow de Dynamic Type: Tamanos grandes frecuentemente causan: texto truncado, labels superpuestos, botones muy pequenos, scrolling horizontal no deseado.
Tips Profesionales
Tip 1: Prueba en la version de iOS mas antigua soportada primero. La mayoria de crashes ocurren en versiones antiguas donde APIs deprecadas se comportan diferente.
Tip 2: Usa Xcode Organizer para datos reales de crashes. Despues del beta testing con TestFlight, Organizer muestra reportes reales de crashes.
Tip 3: Prueba el estado “No Determinado” de permisos. iOS solo muestra el dialogo de permiso una vez. Prueba lo que hace tu app cuando el permiso nunca ha sido solicitado versus cuando fue denegado explicitamente.
Puntos Clave
- Las transiciones del ciclo de vida de iOS son fuente comun de bugs — prueba interrupciones, suspension y restauracion
- XCUITest es el framework nativo de automatizacion de UI de iOS
- Xcode Instruments es esencial para profiling de rendimiento y memoria
- El testing de permisos debe cubrir primera solicitud, denegacion, revocacion y acceso limitado
- Los rechazos del App Store generalmente son por bugs, funciones incompletas o violaciones de guias