Prompts para Testear Apps Móviles con IA: React Native, Flutter y Detox
8 prompts para testear apps móviles con IA: Detox, Appium, pruebas de UI en React Native y Flutter, y tests de integración con Detox.
Tabla de contenidos
Llevo años viendo el mismo ciclo en proyectos móviles: la app sale, todo funciona a mano, y dos semanas después el tester encuentra un botón que se solapa con el teclado en Android. Cuando preguntas por tests E2E, la respuesta es que “en móvil son muy lentos y frágiles”. Y tiene razón, pero por el motivo equivocado. No son frágiles por culpa del móvil: son frágiles porque se escriben igual que en web, esperando a un texto en vez de esperar a un estado.
La otra mitad del problema es la velocidad. Un test E2E en web tarda dos segundos. El mismo test en móvil, con emulador, tarda entre treinta segundos y dos minutos. Cuando sumas quince tests, tu suite local tarda media hora y en CI cuarenta minutos. A partir de ahí, nadie la ejecuta. Una suite que no se ejecuta no existe, por muy bonita que sea.
Aquí es donde la IA cambia el juego, pero con una condición: no sabe qué probar por ti, sabe traducir flujo a código y explicar por qué un test es inestable. Los prompts de este artículo están ordenados por fase real de trabajo: primero diseño de la estrategia, luego los flujos críticos, después selectores, y al final la integración con CI. Si entiendes el orden, el orden importa: un prompt de “genera el test de pago” sin antes haber definido testIDs produce un test que no va a funcionar.
Si todavía estás decidiendo entre stacks, en React Native vs Flutter con Expo hay un desglose que afecta directamente a qué framework de test te conviene. Y la base de prompts del blog está en los 20 mejores prompts para programar con IA.
Antes de pegar nada: cuatro reglas que evitan perder una tarde
- Pega la estructura real de componentes, no una descripción. Si escribes “tengo un botón de login”, la IA inventa un árbol de componentes. Si pegas el JSX del formulario, el test sale con los selectores correctos a la primera.
- Nombra tu framework de test y su versión en el prompt. Detox 20 y Detox 21 no tienen la misma API de sincronización, y el mismo prompt da resultados distintos.
- Pide siempre el porqué de cada espera. Si no explicas las esperas, recibes
waitFor(3000)y un test que se rompe en el CI lento. - Un prompt, un test. Los tests gigantes que recorren toda la app son imposibles de depurar cuando fallan.
Estrategia de testing antes de escribir un solo test
1. Reparte la app en capas de test
Tengo una app móvil en [React Native 0.8x con Expo SDK 54 / Flutter 3.4x].
Módulos: [login, onboarding, carrito, checkout, perfil, notificaciones].
Flujos críticos de negocio: [los 3 que si fallan pierden dinero o datos].
Coste actual de un ciclo completo de QA manual: [X horas].
Proponme una estrategia de testing por capas: qué va como test unitario,
qué como test de integración, qué como E2E y qué NO debe automatizarse.
Justifica cada decisión por coste de mantenimiento vs riesgo de regresión.
No me des código todavía.
Por qué funciona: separa el debate de “qué framework uso” del debate de “qué merece la pena probar”. La mayoría de proyectos automatizan el 100% de la UI y ninguna de la lógica de negocio. Está al revés.
2. Elige framework con criterio, no con moda
| Criterio | Detox | Appium | Maestro (YAML) | Tests manuales |
|---|---|---|---|---|
| Lenguaje | JS/TS | Cualquiera (external driver) | YAML plano | Nada |
| Velocidad (test simple) | ~20-40 s | ~60-120 s | ~15-30 s | Minutos |
| Usa el framework real | Sí (mete el código de la app) | No (black box) | No (black box) | Sí |
| Mantenimiento | Medio | Alto | Bajo | — |
| Multi-plataforma (iOS + Android) | Sí, con campos propios | Sí, con drivers distintos | Sí | Sí |
| Ideal para | E2E de flujos críticos | Suites grandes cross-plataforma | Smoke tests rápidos | Biometría, GPS, cámara real |
| Curva de entrada | Media | Alta | Muy baja | — |
Por qué funciona: casi todo el mundo elige Appium por costumbre corporativa. Con esta tabla la decisión sale sola: si tu app es React Native y tu suite cabe en 20 tests, Detox gana en todo menos en portabilidad. Para un smoke test de 5 flujos en cada commit, Maestro es más rentable que cualquiera de los dos.
Flujos críticos: los tests que de verdad importan
3. Test del flujo de login
Genera un test E2E de login en Detox para una app en [React Native / Flutter].
Framework: [Detox 21].
Pantalla de login con estos componentes: [pegar JSX o estructura equivalente].
Selectores disponibles: testID="email-input", testID="password-input",
testID="submit-button", testID="error-banner".
Variante válida: [usuario@ejemplo.com / contraseña válida].
Variante inválida: [usuario inexistente] que debe mostrar errorBanner.
Requisitos obligatorios:
- Esperas por elemento visible, nunca por tiempo fijo.
- Espera a la desaparición del spinner antes de leer el error.
- test.useRelaunchApp({ launchArgs: { e2e: true } }) para estado limpio.
- Un solo `it` por escenario.
Devuélveme el archivo .e2e.js completo y explica cada espera que has usado.
Por qué funciona: cuando le das los selectores exactos y le exiges justificar las esperas, el test sale directamente en el formato correcto. Sin esa exigencia, mete sleeps y el test pasa en local y falla en CI.
4. Test del flujo de pago (el que siempre duele)
Test E2E del checkout en [React Native / Flutter], framework [Detox 21 / Maestro].
Flujo: añadir producto → carrito → pago con tarjeta de prueba → confirmación.
Elementos: [pegar JSX del carrito y del formulario de pago].
Antes de pagar hay un spinner de "procesando" que puede tardar hasta [8 s].
La pantalla de éxito tiene testID="payment-success".
Si el pago falla, aparece testID="payment-error" con un texto concreto.
Genera el test con:
- Un timeout realista para el spinner (no 2 s).
- Comprobación de que se llega a la pantalla de éxito.
- Un segundo escenario para tarjeta rechazada.
Dime qué parte de este flujo NO es testeable en un emulador y cómo lo cubrirías.
Por qué funciona: el pago es donde fallan los timeouts de verdad. Y la última línea del prompt —preguntarle qué no es testeable— es la que te ahorra perder una semana intentando automatizar algo que depende de un backend real.
5. Test del onboarding
Onboarding de [3 / 4] pantallas con swipes. Cada pantalla tiene testID="step-N"
y la última un botón testID="onboarding-done".
El último paso hace una llamada a la API de registro: mockéala con detox
`launchArgs` y un mock de red, o simula con waitFor del texto de confirmación.
Escribe el test que recorra el onboarding entero y verifique que al terminar
el usuario ve la pantalla principal (testID="home-screen").
Incluye el caso de saltar el onboarding (botón "skip", si existe).
Selectores estables: donde se rompe todo
6. Auditoría de testIDs
Este es el JSX de mis pantallas de [login / checkout / onboarding]: [pegar código].
Audítalo y devuelve una tabla con: componente, ¿tiene testID?,
¿el testID es único en toda la app?, ¿es estable si el texto cambia?,
alternativa propuesta si falta.
Prioriza por los elementos que un E2E necesita tocar.
Dame el diff completo para añadir los que falten.
Por qué funciona: los selectores por texto visible (getByText('Iniciar sesión')) son la causa número uno de tests frágiles. Cualquier cambio de copy los rompe. Con testID sobreviven a todo, y este prompt te da el trabajo hecho.
Ejemplo real de un antes y después:
// ❌ Frágil: si el copy cambia, el test falla
<Button title="Iniciar sesión" onPress={handleLogin} />
// ✅ Estable: sobrevive a cambios de copy, traducibles y estilos
<Button testID="submit-button" title={t('auth.login.submit')} onPress={handleLogin} />
7. Selector cuando no puedes tocar el código
No puedo modificar el componente de terceros [nombre librería] que renderiza [X].
Necesito interactuar con un selector que está dentro de él.
En Detox, ¿qué me da más estabilidad: id nativo, matchers por texto,
por posición en el árbol, o by.id con la ruta AccessibilityId?
Dame el selector más robusto posible y explica su fragilidad.
Por qué funciona: a veces no puedes añadir un testID porque el componente viene de una librería o es un render nativo. Ahí toca saber qué selector degrada menos. La respuesta suele ser by.id con la ruta de accesibilidad nativa, no el texto.
Qué se puede y qué no automatizar
8. Clasificador automatizable / no automatizable
Flujos de mi app móvil: [lista de flujos con dependencias].
Clasifica cada uno en:
- Automatizable en emulador (E2E estable)
- Automatizable solo en dispositivo real
- No automatizable, requiere QA manual
- Mejor como test de integración, no E2E
Criterio: dependencia de hardware, permisos del sistema, servicios de terceros
y sensibilidad a la latencia de red.
Justifica cada decisión en una frase y dámelo en formato tabla.
Por qué funciona: evita que pierdas semanas automatizando el pago con tarjeta real o el login por biometría. Este prompt te da el reparto honesto entre suite automática y checklist manual.
9. Tests de integración con Detox
Quiero tests de integración (no E2E) para mi lógica de negocio móvil en
[React Native / Flutter], con la capa de red mockeada.
Funciones a testear: [pegar código de carrito, cálculo de descuentos, validación].
Dame:
- Un test por función con casos límite (vacío, un elemento, muchos, negativos).
- Mocks de la capa de red sin depender de un servidor externo.
- Tests de casos de error: red caída, 500, timeout.
Usa el runner oficial ([Jest + Testing Library / flutter_test]) sin Detox.
Explica qué diferencia hay entre esto y un E2E en cuanto a qué bugs atrapa.
Por qué funciona: los tests de integración corren en segundos y no tocan emulador. Atrapan la mayoría de los bugs de lógica a una fracción del coste. Si tu cobertura de bugs viene solo de E2E, estás pagando muy caro por muy poca cobertura.
Integración con CI y emuladores
10. Setup de emulador y pipeline
Quiero ejecutar la suite E2E de [Detox/Appium/Maestro] en CI con [GitHub Actions].
Entorno: Ubuntu 24.04, Node 22, Java 21, Android SDK 35 + iOS 16 (opcional).
Suite actual: [X tests, Y minutos].
Genera el workflow completo con:
- Configuración de KVM para que el emulador arranque rápido.
- Estrategia de shard por dispositivo para paralelizar.
- Cache de Gradle y del npm cache.
- Subida de artefactos: capturas y vídeo cuando un test falla.
- Reintentos solo para tests marcados como flaky, nunca global.
Dime qué pasos son los que más ralentizan la suite y cuáles no puedes eliminar.
Por qué funciona: KVM en Linux es la diferencia entre un emulador usable y uno que tarda diez minutos en arrancar. Sin eso, la suite E2E en CI es inviable por motivos puramente de infraestructura, no de tests.
11. Red inestable y tests que dependen de la red
Mis tests E2E fallan de forma intermitente solo en CI. Síntoma: timeout esperando
[elemento] en el test [nombre], pero pasa en local.
Ya tengo esperas por elemento y testIDs.
Dame una lista de causas probables ordenadas por frecuencia en proyectos
[React Native / Flutter] con Detox en CI, y para cada una el arreglo concreto
en código o en el workflow. Incluye: arranque de la app, red real vs mock,
estados de carga, tipografías y recursos, y diferencia de hardware emulado.
Por qué funciona: convertir “flaky” en una lista de hipótesis te ahorra horas de cambiar sleep a ciegas. El arranque de la app en emulador y la red real son las dos causas que más se ignoran.
12. Tests de accesibilidad y de render en móvil
Quiero tests de accesibilidad en mi app [React Native / Flutter]:
contraste de colores, textos escalables, áreas táctiles mínimas y
lectura correcta del accessibilityLabel.
Dame:
- Una checklist de verificación automatizable con las herramientas correctas
para cada plataforma (Android: TalkBack, iOS: VoiceOver).
- El código de un test que verifique que todos mis botones interactivos
tienen accessibilityLabel no vacío y un área táctil de al menos 44x44.
- Cómo integrarlo en el mismo pipeline que los E2E.
Por qué funciona: la accesibilidad es el aspecto más ignorado en móvil y el que más rápido se arregla si tiene un test que falla en CI. Sin ese test, cada sprint la vuelve a romper.
Anti-patrones que veo en todos los proyectos
❌ Selectores por texto visible
// ❌ Se rompe con cualquier cambio de copy o traducción
await element(by.text('Iniciar sesión')).tap();
// ✅ Sobrevive a todo
await element(by.id('submit-button')).tap();
❌ Esperas fijas en cada paso
// ❌ Test lento en local, roto en CI
await element(by.id('loading')).tap();
await waitFor(3000).whileElement(by.id('loading')).exists();
// ✅ Espera por la condición real
await waitFor(element(by.id('loading')))
.not.toExist()
.withTimeout(10000);
❌ Un E2E gigante que recorre toda la app
// ❌ Imposible de depurar, lentísimo, un fallo tumba la suite entera
it('recorre la app completa', async () => {
// login → onboarding → 8 pantallas → checkout → perfil
});
// ✅ Un test por flujo, con nombre que describe el resultado
it('permite comprar con tarjeta válida', async () => {
// login → carrito → pago → confirmación
});
❌ Anti-patrón de arquitectura: E2E para lógica de negocio
// ❌ Probar el cálculo de descuentos lanzando la app 200 veces
// ✅ Probarlo en 20 ms con un test unitario
expect(calculateDiscount(items, 'SUMMER25')).toBe(15);
Errores frecuentes y cómo salir de ellos
- “El test pasa solo la primera vez”: estado residual entre ejecuciones. En Detox,
launchArgs: { e2e: true }másdevice.launchApp({ delete: true }). En Appium,noReseta false. - “En local va bien y en CI no”: emulador más lento, red real, o fuentes que no cargan. Compara el emulador de CI con el tuyo antes de tocar el código del test.
- “El element(by.id(…)) no lo encuentra”: el
testIDno llegó al nodo nativo. En React Native, si untestIDlo lleva un componente que a su vez envuelve a otro nativo, la búsqueda falla. Ponlo en el componente nativo final y vuelve a compilar la app de pruebas, no solo el bundle de JS. - “El vídeo no se sube cuando falla”: los artefactos se generan solo si el job reporta
test-results/. Revisa elif: always()en el workflow y las rutas del artefacto. - “La suite tarda una hora y nadie la ejecuta”: no es un problema de la suite, es un problema de alcance. Vuelve al prompt 1 y recorta a los flujos críticos.
El flujo completo
┌─────────────────────────────────────────────────────────┐
│ 1. Prompt 1: capas de test (qué merece automatizarse) │
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 2. Prompt 2: elegir framework con la tabla │
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 3. Prompt 6: testIDs en TODO lo que el E2E toque │
│ ⚠️ Antes de escribir un solo test │
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 4. Prompts 3-5: tests de flujos críticos │
│ (login, pago, onboarding) │
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 5. Prompt 9: tests de integración (lógica, sin emulador)│
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 6. Prompt 8: clasificar lo NO automatizable → QA manual│
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 7. Prompt 10: CI con KVM + sharding + artefactos │
└────────────────────────┬────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────┐
│ 8. Prompts 11-12: flakes y accesibilidad │
└─────────────────────────────────────────────────────────┘
El orden importa: los testIDs van antes que los tests porque un test escrito sin ellos se reescribe entero. Y la clasificación de lo no automatizable va antes del CI, porque determina cuánta gente necesitas para el testing manual.
Conclusión
La IA no te va a decir qué test escribir: eso es producto. Lo que sí hace muy bien es convertir un flujo en un test correcto, explicarte por qué un test es inestable y auditar si tus selectores sobrevivirán al próximo cambio de diseño. Usado con ese orden, pasas de “no testeo móvil porque es una pesadilla” a tener una suite corta, estable y de treinta segundos que se ejecuta en cada commit.
La parte que sigue siendo 100% tuya es decidir qué no automatizar y escribir los tests de caracterización que congelan el comportamiento actual. Eso lo cubro en detalle en prompts para migrar código legacy, que es exactamente el mismo problema cuando el código no lo escribiste tú.
Si ya tienes tests unitarios generados por IA y quieres saber cuáles te están dando falsa confianza, mira testear el código generado por Copilot y Cursor. Y si quieres montar el prompt a medida, tienes el generador de prompts.
Sigue aprendiendo: