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
EstadoDescripcionFoco de Testing
No EjecutandoApp no lanzada o terminadaRendimiento de inicio en frio
InactivaEn primer plano pero sin recibir eventosManejo de interrupciones
ActivaEn primer plano recibiendo eventosFuncionalidad normal
Segundo PlanoEjecutando codigo pero no visibleCompletar tareas de fondo
SuspendidaEn memoria pero sin ejecutar codigoRestauracion de estado
TerminadaRemovida de memoriaPersistencia de datos

Escenarios Criticos de Testing

  1. 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.

  2. 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
  3. 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
  4. 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:

InstrumentoPropositoCuando Usar
Time ProfilerAnalisis de uso de CPUApp se siente lenta
AllocationsRastreo de uso de memoriaAlto consumo de memoria
LeaksDeteccion de fugas de memoriaLa memoria crece con el tiempo
Energy LogConsumo de bateriaDrenaje de bateria en segundo plano
NetworkProfiling de requests de redCarga 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

PermisoPrimera SolicitudDespues de DenegacionMetodo de Reset
CamaraDialogo del sistemaDebe ir a ConfiguracionConfiguracion > Privacidad > Camara
Ubicacion3 opciones: Una vez, Al usar, SiempreSolo ConfiguracionConfiguracion > Privacidad > Ubicacion
NotificacionesDialogo del sistemaSolo ConfiguracionConfiguracion > Notificaciones
FotosDialogo con acceso limitado/completoSolo ConfiguracionConfiguracion > 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

  1. Bugs y crashes (mas comun) — Prueba todos los flujos en la version minima soportada de iOS
  2. Links rotos y contenido placeholder — Verifica todas las URLs en la app
  3. Metadata incompleta — Screenshots deben coincidir con UI actual
  4. Problemas de rendimiento — El lanzamiento debe completarse en tiempo razonable
  5. 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:

  1. Usuario agrega items al carrito, recibe una llamada, regresa a la app 5 minutos despues
  2. Usuario otorga permiso de ubicacion como “Al usar la app” pero la app necesita ubicacion para rastreo de entrega en segundo plano
  3. Usuario tiene Dynamic Type en el tamano mas grande de accesibilidad
Solucion
  1. 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.

  2. 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.

  3. 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