Hay una escena que se repite en casi todos los proyectos mobile: la suite de regresión pasa en verde en el pipeline, el release sale a producción, y a las dos horas empiezan a llegar los reportes. Crashes en Samsung con Android 13. La cámara que no abre. El login biométrico que devuelve un error genérico.
Los tests no estaban mal. Estaban corriendo en el lugar equivocado.
Esta es una de las decisiones técnicas que más impacto tiene en la calidad de una app y que, sin embargo, suele tomarse por defecto: dónde ejecutás tu automatización mobile.
Primero, una distinción que importa
Se usan como sinónimos, pero no son lo mismo.
Un emulador (Android) emula el hardware completo: la CPU, la GPU, los sensores, la capa de radio. Corre una imagen real del sistema operativo sobre una máquina virtual. Por eso es lento, y por eso es más fiel.
Un simulador (iOS) no emula hardware. Ejecuta tu app compilada para la arquitectura de tu máquina, dentro de un entorno que imita el comportamiento de iOS. Es rápido, liviano y bastante menos fiel: el binario que probás no es exactamente el binario que va a la App Store.
Un dispositivo real es un teléfono. Con su procesador, su batería, su versión de Android modificada por el fabricante, su antena y su usuario apurado.
La consecuencia práctica: un test que pasa en el simulador de iOS te dice mucho menos de lo que creés.
Qué detecta bien un emulador
No son un mal necesario. Bien usados, resuelven la mayor parte del volumen de testing:
- Lógica de negocio y flujos funcionales. Si el carrito calcula bien el total, el emulador te lo dice igual que un iPhone.
- Navegación y estados de UI. Pantallas, transiciones, validaciones de formularios, mensajes de error.
- Cobertura de versiones de OS. Levantar imágenes de Android 11, 13, 14 y 15 en paralelo cuesta minutos, no plata.
- Resoluciones y densidades. Probar layouts en pantallas chicas y tablets sin comprar hardware.
- Regresión en cada commit. Acá es donde brillan: son descartables, reproducibles y arrancan desde un estado limpio siempre.
Ese último punto es el más importante. Un emulador se puede tirar y volver a levantar. Un dispositivo real acumula estado, se queda sin batería, pierde el wifi y alguien se lo lleva a una demo.
Qué no vas a detectar nunca en un emulador
Y acá está la lista que explica los bugs de producción:
- Fragmentación de fabricantes. Android no es Android. Es One UI de Samsung, HyperOS de Xiaomi, ColorOS de Oppo. Cada capa toca permisos, gestión de memoria en background, notificaciones y comportamiento del teclado. El emulador corre Android puro (AOSP), que casi nadie tiene en la mano.
- Performance real. El emulador usa la CPU y la RAM de tu máquina o de tu runner de CI. Un dispositivo de gama baja con 3 GB de RAM y el sistema matando procesos en background se comporta de otra manera. Los tiempos de carga, el jank en scroll y los ANR aparecen solo ahí.
- Hardware y sensores. Cámara, NFC, GPS con señal real, acelerómetro, huella, Face ID, lector de QR. Se pueden mockear, y el mock valida tu código, no la integración.
- Condiciones de red. 3G intermitente, cambio de wifi a datos en medio de una transacción, latencia de red móvil real. Un emulador tiene la fibra de tu oficina.
- Batería, temperatura y throttling. Ninguna app de banca falla en el laboratorio; falla en el teléfono del cliente al 8% de batería.
- Integraciones con apps de terceros. Tokenización de pagos, deep links a apps de banco, biometría del sistema, Google Pay. Los flujos que salen de tu app y vuelven casi nunca funcionan igual en un entorno emulado.
La estrategia híbrida: no es “uno u otro”, es “cuál en cada capa”
La respuesta correcta no es elegir. Es distribuir la ejecución según el momento del ciclo y el costo de cada corrida.
| Capa | Dónde corre | Qué se ejecuta | Frecuencia |
|---|---|---|---|
| Desarrollo local | Emulador / simulador | El test que estás escribiendo | Permanente |
| Commit / Pull Request | Emuladores en CI | Smoke: 15 a 30 casos críticos | En cada push |
| Regresión nocturna | Emuladores en paralelo, múltiples versiones de OS | Suite completa | Diaria |
| Pre-release | Dispositivos reales en device farm | Flujos críticos de negocio + hardware | Por release |
| Post-release | Dispositivos reales, top de mercado | Monitoreo de flujos vitales | Semanal |
La lógica es económica y de riesgo. El emulador te da volumen barato y feedback rápido. El dispositivo real te da certeza donde equivocarse cuesta plata: pago, login, onboarding, alta de cuenta.
Un criterio simple para el subset de dispositivos reales: tomá los datos de analytics de tu propia app. En Latinoamérica, cubrir el 70% de la base instalada suele requerir entre 6 y 10 combinaciones de modelo y versión de OS. No hace falta un catálogo de 200 dispositivos; hace falta el correcto.
Cómo se traduce esto en el framework
Que la misma suite corra en un emulador local y en un dispositivo real de una granja no es magia: es diseño.
- Capabilities parametrizadas, no hardcodeadas. El
deviceName, laplatformVersiony eludidsalen de configuración o de variables de entorno. Un solo test, cinco targets de ejecución. - Abstracción de la capa de hardware. Si tu test necesita escanear un QR, la acción se define en una interfaz. Una implementación inyecta la imagen en el emulador; la otra usa la cámara del dispositivo real. El caso de prueba no cambia.
- Esperas explícitas, siempre. Es la fuente número uno de flakiness al mover tests entre entornos. Un emulador en un runner cargado puede ser tres veces más lento que un teléfono físico. Si tu test depende de un
sleep(2), se va a romper. Condiciones de espera sobre el estado de la UI, nunca sobre el reloj. - Estado controlado desde el inicio. Idioma, zona horaria, permisos, densidad de pantalla y datos de sesión definidos por configuración antes de cada corrida. Los tests que asumen el estado del entorno no son tests, son suerte.
- Animaciones desactivadas en emuladores de CI. Baja el tiempo de ejecución y elimina una categoría entera de fallos intermitentes.
Los errores que vemos más seguido
- Automatizar todo en emuladores y llamarlo cobertura. Da tranquilidad falsa: el reporte está verde y los bugs siguen llegando.
- Automatizar todo en dispositivos reales. Caro, lento, con colas de espera en la granja y feedback que llega cuando ya nadie lo mira.
- Medir performance en un emulador. Los números no significan nada. Ni como baseline.
- No versionar la configuración del entorno. Si cada máquina levanta su propia imagen de Android, los resultados no son comparables.
- Empezar por la UI. La automatización mobile es la capa más costosa y más frágil de la pirámide. Si la capa de API no está automatizada, la UI va a estar tapando agujeros que no le corresponden.
En resumen
El emulador no reemplaza al dispositivo real y el dispositivo real no escala. La pregunta no es cuál elegir, sino qué corre en cada capa, con qué frecuencia y para responder qué pregunta.
Una estrategia mobile sana se parece a esto: volumen en emuladores, certeza en dispositivos reales, y una sola suite mantenible que corre en los dos sin tocar una línea de código.
En Qualis Lab automatizamos regresión mobile con Appium y frameworks propios, ejecutando en emuladores y en dispositivos físicos reales a través de BrowserStack y Sauce Labs. Si querés saber dónde está el punto débil de tu estrategia actual, agendá un diagnóstico de 20 minutos.