La serie arrancó con Mobile Testing: el elefante en la sala que la mayoría de QAs en LATAM ignoramos — la pieza opinión sobre por qué este gap existe. Siguió con Tu primer test mobile en 30 minutos — el hands-on local con Maestro CLI + Maestro Studio Desktop. Esta tercera pieza cierra el arco llevándolo a CI: en lugar de correr Maestro en tu máquina, corre solo en cada push y cada PR del equipo. Si no hiciste la Parte 2, esta guía asume que ya tienes Maestro CLI funcionando local.
Hoy CI mobile deja de ser doloroso. Pero antes del primer push, la pregunta honesta que cualquier QA se hace cuando ve “Maestro en CI”: ¿esto va a correr el lunes en mi pipeline, o es teoría con repo de juguete?
Spoiler: el repo que vas a forkear corre Maestro en GitHub Actions verde en 2 minutos 10 segundos, primer intento, cero debug. Lo validé tres veces (verde inicial, force-fail para verificar artifacts, verde de cleanup) antes de publicar esta guía. Los tres runs están vivos en adrianagit87/calidad-sin-humo-mobile-ci-maestro, los puedes inspeccionar uno por uno. Lo único que cambia entre ese repo y tu pipeline real son tres líneas. Te las marco al final.
¿Por qué CI mobile fue históricamente un sufrimiento?
El dato simple: hasta 2024, levantar un emulador Android en un runner de CI tardaba 15 minutos. Cada vez. En cada PR. Multiplicalo por una suite de 50 PRs por semana y entiendes por qué la mayoría de equipos LATAM tienen Maestro corriendo en la laptop de un QA y nada más.
| CI mobile circa 2022 (Appium + Selenium Grid) | CI mobile con Maestro + GitHub Actions 2026 |
|---|---|
| 200+ líneas de YAML por workflow | 52 líneas de YAML, una sola action externa |
| Boot del emulador: 12-15 min sin acceleration | Boot del emulador: 90 segundos con KVM en Linux |
| Capabilities de Appium dependientes del cliente Java | Maestro CLI: install con curl + un comando |
| Screenshots: implementación manual con drivers nativos | Screenshots: automáticas en cada fallo, sin código extra |
| Mantenimiento: alta — frágil ante cambios de versión | Mantenimiento: bajo — versiones pineables, ecosistema estable |
La diferencia no es solo cuantitativa. Tres piezas técnicas se alinearon en los últimos 2 años para que esto sea viable, y vale la pena nombrarlas para que entiendas dónde mirar cuando algo se rompa:
-
KVM (Kernel Virtual Machine) — la aceleración por hardware del emulador. En palabras simples: sin KVM, una máquina virtual (como el emulador Android) emula el CPU por software, y eso es ~15 veces más lento. CON KVM, la máquina virtual aprovecha el CPU físico directamente. Resultado concreto: el emulador Android tardaba 15 minutos en bootear, ahora bootea en 90 segundos. GitHub habilitó KVM en sus runners Linux a mediados de 2024 — ese fue el cambio que destrabó todo. (Las 3 líneas raras de
echo 'KERNEL=="kvm"...'que vas a ver en el workflow.yml son exactamente la configuración que habilita ese acceso.) -
Runners Linux gratis del free tier de GitHub. Los “runners” son las máquinas que GitHub te presta gratis para correr tu CI. El free tier te da 2000 min/mes en Linux contra 200 min/mes en macOS — Linux te rinde 10 veces más. Antes de KVM, Linux no servía para Android (emulador inutilizablemente lento) y había que pagar macOS o Maestro Cloud. Ahora Linux gana en todo.
-
La GitHub Action
reactivecircus/android-emulator-runner. Una “Action” en GitHub Actions es como un plugin reusable que alguien de la comunidad publicó. Esta action específica sabe levantar un emulador Android, esperar a que bootee, ejecutar tu script de tests, y cerrarlo al final. Sin ella, tendrías que escribir 100+ líneas de YAML manejando todo eso a mano. Con ella, son 6 líneas en tu workflow.
Las tres juntas son la receta que hace viable correr Maestro en CI gratis para repos personales y equipos chicos. Antes la única alternativa era pagar Maestro Cloud o tragar runners macOS 10x más caros.
Pre-requisitos
- Tener Maestro CLI funcionando local (lo cubrimos en Parte 2)
- Cuenta GitHub gratis
- Eso es todo. No necesitas Android Studio, no necesitas SDK manager local, no necesitas Java en tu máquina
1. Forkea y arranca: verde en 5 minutos
Antes de explicarte una sola línea del workflow.yml, quiero que veas verde con tus propios ojos. La regla pedagógica de esta serie: primero corre, después entiende.
Paso 1 — Forkear el repo
¿Qué significa “hacer fork”? Es crear una copia personal del repo en tu cuenta de GitHub. La copia queda independiente del original — puedes modificarla todo lo que quieras sin afectar el repo del autor. Es lo que necesitas para que GitHub Actions corra el workflow contra TU copia, usando los minutos gratis de TU cuenta.
Ve a adrianagit87/calidad-sin-humo-mobile-ci-maestro, haz click en el botón “Fork” arriba a la derecha, y confirma. En 5 segundos tienes tu copia en tu-usuario/calidad-sin-humo-mobile-ci-maestro. El repo es público, licencia MIT, diseñado para forkear y aprender.
Paso 2 — Habilitar Actions en tu fork
GitHub deshabilita Actions por default en forks por seguridad. Ve a la pestaña Actions de tu fork y haz click en “I understand my workflows, go ahead and enable them”. Una sola vez, ya queda activo.
Paso 3 — Disparar el primer run
Tenés tres opciones:
# Opción A: push trivial (modifica el README, commit, push)git clone https://github.com/TU-USUARIO/calidad-sin-humo-mobile-ci-maestro.gitcd calidad-sin-humo-mobile-ci-maestroecho "" >> README.mdgit commit -am "chore: trigger CI"git push# Opción B: workflow_dispatch desde la UI# Ve a Actions > Maestro CI > Run workflow > Run workflow# Opción C: abre un PR contra main# El workflow corre también en pull_requestPaso 4 — Ver el run
Vuelve a la pestaña Actions. Vas a ver tu workflow con un círculo amarillo (queued), después azul (in progress), después verde (success). En total: ~2 minutos.
En 5 minutos te montaste un pipeline de CI mobile completo. Sin instalar Android Studio, sin pelearte con SDK, sin tocar Java en tu máquina. La infraestructura está en GitHub. Tú solo gestionas flows YAML. Eso ya es la promesa de Maestro hecha realidad.
Pero ahora la pregunta: ¿qué hace ese workflow.yml por debajo, y cómo lo adaptas a tu app real? Para eso necesitas entender línea por línea. Vamos.
2. El workflow.yml verificado, línea por línea
Acá está el archivo completo, las 52 líneas que validé en CI:
name: Maestro CI
on: push: branches: [main] pull_request: branches: [main] workflow_dispatch:
jobs: smoke-test: name: Smoke test (Android API 33) runs-on: ubuntu-latest timeout-minutes: 20
steps: - name: Checkout uses: actions/checkout@v4
- name: Enable KVM acceleration run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvm
- name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: "17" distribution: "temurin"
- name: Install Maestro CLI run: | curl -fsSL https://get.maestro.mobile.dev | bash echo "$HOME/.maestro/bin" >> $GITHUB_PATH
- name: Run Maestro on Android emulator uses: reactivecircus/android-emulator-runner@v2 with: api-level: 33 arch: x86_64 profile: pixel_6 emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim disable-animations: true script: | maestro download-samples adb install -r samples/wikipedia.apk maestro test .maestro/
- name: Upload artifacts on failure if: failure() uses: actions/upload-artifact@v4 with: name: maestro-failure-${{ github.run_number }} path: | ~/.maestro/tests/** **/*.png retention-days: 7Vamos por bloques.
2.1 — Triggers: cuándo corre el workflow
on: push: branches: [main] pull_request: branches: [main] workflow_dispatch:Tres triggers, cada uno con un propósito distinto:
push: branches: [main]— corre cuando haces merge a main. Es tu smoke continuo de la rama principal.pull_request: branches: [main]— corre cuando alguien abre un PR contra main. Es el gate de calidad: si Maestro falla, el PR queda marcado en rojo. Este es el trigger que cambia la cultura del equipo.workflow_dispatch— habilita el botón “Run workflow” en la UI de GitHub. Útil para correr el workflow manualmente sin hacer push, por ejemplo después de actualizar un secret o para re-validar después de un cambio externo.
Una vez que tu suite empieza a crecer, vale la pena agregar un cuarto trigger: schedule con cron para correr el smoke todas las noches automáticamente.
on: schedule: - cron: "0 3 * * *" # 03:00 UTC todos los díasPor qué importa: detecta lo que llamamos “drift externo” — cambios en cosas que NO controlas (el CDN de Maestro samples, nuevas versiones del emulator action, breaking changes en Android API). Si tu smoke pasa verde en cada push durante la semana pero falla un martes a las 3am, sabes que algo del ecosistema cambió, no tu código. Es la primera línea de defensa contra el “funcionaba el viernes y el lunes no, ¿qué pasó?”.
No lo incluí en el workflow base de esta guía porque agrega complejidad antes del valor core. Cuando tu suite crece más allá del smoke test, agrégalo — son 3 líneas.
2.2 — Runner y timeout
runs-on: ubuntu-latesttimeout-minutes: 20Linux, no macOS. Esta es la decisión más importante del workflow. macOS runners cuestan 10x más minutos del free tier de GitHub (200 min/mes en macOS vs 2000 min/mes en Linux). Con KVM habilitado en Linux desde mediados de 2024, ya no hay ventaja real de macOS para Android. La única razón para usar macOS sería testing iOS — y para eso tienes otra historia (xcrun simctl, no adb install).
timeout-minutes: 20 es protección: si algo se cuelga (emulator boot infinito, Maestro test que loopea), GitHub mata el job a los 20 min en lugar de gastarte minutos del free tier indefinidamente.
2.3 — Habilitar KVM
- name: Enable KVM acceleration run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules sudo udevadm control --reload-rules sudo udevadm trigger --name-match=kvmKVM (Kernel Virtual Machine) es la aceleración por hardware que hace que el emulador Android arranque en 90 segundos en lugar de 15 minutos. Estas tres líneas configuran los permisos de /dev/kvm para que el action de emulator pueda usarlo.
Sin estas líneas, el emulator boot tarda 15x más. Las copias textual y olvidas que existen.
2.4 — JDK 17 + Maestro CLI
- name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: "17" distribution: "temurin"
- name: Install Maestro CLI run: | curl -fsSL https://get.maestro.mobile.dev | bash echo "$HOME/.maestro/bin" >> $GITHUB_PATHJDK 17 lo necesita el Android SDK por debajo. Distribución temurin es la libre de Eclipse Adoptium.
Maestro se instala con el script oficial (curl -fsSL https://get.maestro.mobile.dev | bash), que pone el binario en $HOME/.maestro/bin. La línea echo "..." >> $GITHUB_PATH agrega esa ruta al PATH para que los siguientes steps puedan llamar maestro sin path absoluto.
2.5 — El action que hace todo el trabajo pesado
- name: Run Maestro on Android emulator uses: reactivecircus/android-emulator-runner@v2 with: api-level: 33 arch: x86_64 profile: pixel_6 emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim disable-animations: true script: | maestro download-samples adb install -r samples/wikipedia.apk maestro test .maestro/Este step usa reactivecircus/android-emulator-runner@v2, el estándar de facto para emulador Android en GitHub Actions. Manejado por la comunidad, 1.5k+ repos lo usan.
Qué hace cada parámetro:
| Parámetro | Para qué sirve |
|---|---|
api-level: 33 | Android 13. Es el mismo nivel que usaste en la Parte 2 — así no rompes nada del setup que ya validaste local. |
arch: x86_64 | Arquitectura del emulador. x86_64 es compatible con runners Intel/AMD64 sin emulación cruzada. |
profile: pixel_6 | Perfil de hardware. Pixel 6 es el más cercano al device promedio que vas a testear en producción. |
emulator-options: -no-window ... | Headless, sin UI, sin audio, sin animation de boot. Cada flag suma 10-30s ahorrados. |
disable-animations: true | Apaga las animaciones del SO. Tests más rápidos y más estables. |
script: | Acá adentro corre tu lógica con el emulador ya booteado. |
El bloque script: son las tres líneas que importan:
maestro download-samples— descargasamples/wikipedia.apkdesde el CDN oficial de Maestroadb install -r samples/wikipedia.apk— instala el APK en el emulador (el-rpermite reinstall si ya está)maestro test .maestro/— corre todos los.yamlde la carpeta.maestro/
2.6 — Artifacts on failure (lo cubrimos en la sección 3)
- name: Upload artifacts on failure if: failure() uses: actions/upload-artifact@v4 with: name: maestro-failure-${{ github.run_number }} path: | ~/.maestro/tests/** **/*.png retention-days: 7Este step solo se ejecuta cuando algo falló (el if: failure() lo controla). Sube los outputs de Maestro + cualquier PNG generado. Te explico el detalle en la siguiente sección, porque acá es donde está la diferencia entre “fallo críptico de CI” y “debug del lunes a la mañana en 5 minutos”.
3. Cuando algo falla: los artifacts
La promesa de cualquier guía de CI es “te aviso cuando falla”. La promesa que pocas guías cumplen es “te doy el contexto suficiente para que entiendas POR QUÉ falló sin reproducirlo local”. Maestro la cumple, gratis.
Para verificar esto, en mi setup hice un force-fail deliberado: agregué un flow con assertVisible: "TextoInexistenteParaForzarFallo" y pusheé. Run #26205431483 falló a los 2 minutos 34 segundos. El step Upload artifacts on failure se ejecutó automáticamente. Esto fue lo que GitHub puso disponible para descargar:
| Lo que esperarías en un CI “estándar” | Lo que Maestro te da gratis en CI |
|---|---|
| Un log de texto con la línea del fallo | Auto-screenshot del momento exacto del fallo (con ❌ literal en el nombre del archivo) |
| Tal vez stack trace | Log estructurado JSON de cada comando con timing |
| Abres el emulador local y reproduces | Maestro.log completo (17 KB) |
| Reproducción promedio: 20-40 min | Screenshots manuales de los takeScreenshot pre-fallo |
| Debug promedio: 5-10 min sin abrir tu máquina |
Cómo descargas el artifact
Cuando un workflow falla, ve al run en la pestaña Actions y en el bottom encuentras la sección Artifacts. Haces click en maestro-failure-{run_number} y bajas un ZIP. Adentro tienes esta estructura:
maestro-failure-2/├── .maestro/tests/2026-05-21_043007/│ ├── commands-(01-smoke).json # 1.2 KB — log estructurado smoke│ ├── commands-(02-force-fail).json # 89 KB — log estructurado del flow que falló│ ├── maestro.log # 17 KB — log textual de toda la ejecución│ └── screenshot-❌-1779337835196-(02-force-fail).png # 176 KB — AUTO-SCREENSHOT└── work/calidad-sin-humo-mobile-ci-maestro/ ├── 01-launch.png # screenshot manual smoke que pasó └── 01-before-fail.png # screenshot manual del flow que iba a fallarEl auto-screenshot del fallo es la pieza que cambia todo
Mira el nombre del archivo: screenshot-❌-1779337835196-(02-force-fail).png. Ese ❌ es literal en el filename. Maestro toma una captura del estado del emulador exactamente en el momento en que el assert falla, sin que la pidas. Si tu test rompía porque cambiaron un botón de lugar, vas a ver el botón en su nueva posición sin tener que reproducirlo en tu máquina.
Esto es lo que separa un CI “que avisa que hay fallo” de un CI “que te da contexto para arreglarlo sin reproducir local”. Si automatizas mobile sin tener esto, estás dejando 30 minutos sobre la mesa cada vez que algo rompe.
Por qué if: failure() y no always
Una decisión deliberada del workflow: artifacts SOLO en fallos, no en cada run. Razones:
- Storage: cada artifact con screenshots ronda 1.5-3 MB. Si subes en cada run verde, en 1 mes tienes 5 GB de artifacts inútiles que GitHub te cobra a partir del free tier.
- Foco: cuando entras a un run, si hay artifact disponible es porque pasó algo interesante. Si siempre hay, dejas de mirarlo.
- Retención:
retention-days: 7automáticamente borra los artifacts viejos. Una semana es suficiente para que reacciones al fallo, sin acumular basura.
4. De Wikipedia a TU app en CI
Hasta acá tu workflow corre Maestro contra Wikipedia oficial. Para que sirva en producción tienes que cambiar 3 cosas. Solo 3. El resto del YAML queda idéntico.
Los 3 cambios
| Pieza | En el repo demo | En tu pipeline real |
|---|---|---|
| De dónde sale el APK | maestro download-samples (baja Wikipedia desde el CDN oficial de Maestro) | Donde tu equipo lo guarda: un release de GitHub, un bucket en la nube, o el archivo que produce tu job de build |
appId en los flows | org.wikipedia | com.tuempresa.tuapp |
| Selectores en los flows | org.wikipedia:id/search_container | com.tuempresa.tuapp:id/login_btn |
Para el primero, las tres opciones más comunes que veo en repos reales:
# Opción A — APK como artifact de un build job previo- name: Download APK from build job uses: actions/download-artifact@v4 with: name: app-debug.apk path: builds/# Opción B — APK desde GitHub Releases (releases privados con token)- name: Download APK from latest release run: gh release download -p "*.apk" -R tu-org/tu-app -D builds/ env: GH_TOKEN: ${{ secrets.GH_TOKEN }}# Opción C — APK desde Google Cloud Storage- name: Download APK from GCS run: gcloud storage cp gs://tu-bucket/builds/latest.apk builds/Y después en el script del emulator-runner:
script: | adb install -r builds/*.apk maestro test .maestro/Lo demás queda exactamente igual. Mismo reactivecircus/android-emulator-runner, mismos api-level: 33, mismas líneas de KVM, mismo artifact on failure.
Las 3 trampas reales del primer día
Cuando hagas esta migración, te vas a chocar con estas tres cosas. Te las marco para que las anticipes.
Trampa 1 — APK ofuscado en release builds. Si tu build de producción usa ProGuard/R8 (las herramientas que comprimen y “ofuscan” el código Android para hacerlo más liviano y difícil de leer por afuera), los IDs de los elementos de UI llegan a Maestro como :id/a, :id/b, :id/c — letras sin sentido. Maestro no puede tapearlos por ID porque esas letras cambian en cada release.
Solución concreta: en el próximo refinement le pides al equipo dev esto exacto: “Necesitamos que el script de build genere DOS variantes en cada compilación — una debug SIN ProGuard/R8 que apunta a CI de QA, y la release con todo activado que va a Play Store. Son ~5 líneas en build.gradle.” Casi todos los proyectos Android ya manejan este patrón internamente (se llama “build variants”), solo que el equipo QA muchas veces no se entera. Mientras consigues eso, hay un workaround: pídele al equipo dev que les agreguen accessibility IDs (etiquetas semánticas tipo accessibility-id="login_button") a los 5-10 elementos críticos. Los accessibility IDs son metadata aparte del código compilado y sobreviven a la ofuscación.
Trampa 2 — AAB en lugar de APK. Desde 2021 Google obliga a publicar a Play Store usando AAB (Android App Bundle), un formato más nuevo que el APK clásico. Si tu equipo dev publica directo a Play Store, lo que vas a recibir es un .aab. Maestro no lo instala directo — solo entiende .apk.
Solución concreta: dos caminos posibles.
- Camino fácil (recomendado): convences al equipo dev de generar un APK debug paralelo solo para CI de QA. Son las mismas ~5 líneas en
build.gradleque mencioné en Trampa 1 — un solo cambio cubre ambas trampas. APK debug para QA, AAB para Play Store. Cero conflicto. - Camino complicado: instalas
bundletool(herramienta oficial de Google) en el runner y extraes el APK del AAB en tiempo de CI conbundletool build-apks --bundle=app.aab --output=app.apks. Funciona pero suma minutos al runner y un punto extra de fallo. Evítalo si puedes pelear por el camino fácil.
Trampa 3 — Tests que necesitan datos de seed (usuarios, productos, configuración). Si tu flow asume que existe un usuario qa@empresa.com / test123 o un producto con código SKU-001, ese dato tiene que existir en el ambiente al que apunta tu emulador. Esto NO es trampa de Maestro — es trampa de cualquier suite E2E (web o mobile, da igual).
Solución concreta, ordenada de más fácil a más sofisticada:
- Tests pre-login únicamente. Tu primera versión de CI mobile prueba solo flujos que NO requieren autenticación: onboarding, búsqueda pública, navegación entre secciones. Cero setup de datos. Para empezar es perfecto y ya te valida toda la infraestructura.
- Step de seed antes de los flows. Antes del
maestro test, agregas un step en el workflow que llama a un endpoint admin de tu ambiente staging para crear el dato. Ejemplo concreto:curl -X POST https://staging.tuempresa.com/admin/test-user -d email=qa@test.com. Requiere coordinación con el equipo backend para que expongan ese endpoint solo en staging (NUNCA en producción). - Feature flag de “modo testing”. El equipo dev habilita un flag tipo
ALLOW_TEST_USERS=trueque solo está activo en builds de QA. Con el flag prendido, la app permite crear usuarios con dominio@test.comsin pasar verificaciones de email/SMS. Requiere varios sprints de coordinación pero es la solución más escalable cuando tu suite supera los 20-30 flows.
¿Qué hago con iOS?
La mayoría de esta guía aplica con cambios menores. La gran diferencia: en lugar de runner Linux + emulador Android, necesitas macOS runner + Simulator iOS. Eso implica:
runs-on: macos-13(más caro en minutos)- En lugar de
reactivecircus/android-emulator-runner@v2, usasxcrun simctldirecto en bash - En lugar de
.apk, manejas.appbundle o.ipa - En lugar de
adb install, usasxcrun simctl install booted ruta/al/app
El resto: el YAML de Maestro flow es ~95% idéntico (sin obfuscation issues equivalentes en iOS). Esta es la ventaja real de elegir Maestro sobre Appium: cross-platform con curva de aprendizaje menor.
5. Maestro Cloud vs runner propio: cuándo conviene cada uno
Maestro Cloud es la oferta paid del equipo de Maestro: ellos manejan los devices/emuladores en su infraestructura, tú solo pusheas tus flows y recibes resultados. Cuesta desde USD $50/mes para teams chicos, plan free trial para evaluar.
Disclaimer honesto: no probé Maestro Cloud en este hands-on. La comparativa que sigue está basada en docs oficiales, posts de comunidad, y benchmarks publicados — no en pruebas mías. Si llegas al punto donde lo necesitas y tienes data real, escríbeme y la actualizo.
| Runner propio (lo que armamos en esta guía) | Maestro Cloud |
|---|---|
| Gratis hasta 2000 min/mes (free tier GitHub) | Desde USD $50/mes según volumen |
| Setup: 1 hora la primera vez, 0 después | Setup: 15 min (sign up + token + workflow) |
| Tests sobre Android emulator (no devices reales) | Tests sobre devices reales O emuladores cloud |
| Tiempo por run: 2-3 min | Tiempo por run: ~1-2 min (infra dedicada) |
| Debug: artifact con auto-screenshot | Debug: dashboard web + replay video |
| Sin paralelización gratis (1 job a la vez en free tier) | Paralelización gratis incluida en el plan |
Mi recomendación honesta
Empieza con runner propio. Migra a Maestro Cloud cuando:
- Tu suite supere 50 flows y los runs en GitHub Actions tarden >15 min
- Necesites testear en devices reales (no emulator), por ejemplo para validar performance, sensors, o quirks de hardware específicos
- Estés pagando GitHub Actions Pro/Enterprise y los minutos sigan siendo cuello de botella
- Tu equipo necesite el dashboard de Cloud para que stakeholders no técnicos vean resultados sin entrar a GitHub
Si estás arrancando, runner propio cubre el 90% de los casos en LATAM. No te apures a pagar.
Cierre — qué tienes ahora
Si seguiste la guía completa, en estos 25 minutos pasaste de “nada en CI” a:
- ✅ Un repo público forkeado con Maestro corriendo en GitHub Actions
- ✅ Workflow.yml de 52 líneas que entiendes línea por línea
- ✅ Trigger en cada push a main y en cada PR
- ✅ Auto-screenshot del fallo + log estructurado cuando algo rompe
- ✅ El patrón de 3 cambios para llevarlo a tu app real
- ✅ Criterio para decidir si y cuándo migrar a Maestro Cloud
Mobile testing en CI fue durante años el cuello de botella que separaba a los equipos que automatizaban en serio de los que decían que automatizaban. Maestro + GitHub Actions + KVM en Linux lo aplanó. La pregunta ya no es “¿se puede?”. La pregunta es por qué tu equipo todavía no lo tiene.
Cierre de la serie Mobile Testing
Esta guía cierra el arco que arrancó con el elefante en la sala y siguió con tu primer test mobile en 30 minutos. Si las tres piezas las hiciste hands-on, tienes base sólida para llevar mobile testing a tu equipo HOY. No es teoría más. Es práctica con código que corre.
Lo que viene después en el blog sobre mobile, sin fechas comprometidas:
- Playwright para mobile web —
calidadsinhumo.comes una PWA (Progressive Web App: un sitio web que se puede instalar como app desde el browser, sin pasar por la Play Store). Testeada con Playwright emulando iPhone 15 y Pixel 5. Cuándo conviene esto en lugar de Maestro nativo. - Appium vs Maestro vs Detox en 2026 — comparativa post-experiencia, no antes. Cada uno tiene su nicho.
- Testing de gestos complejos en mobile — swipe-to-delete, pinch-to-zoom, long-press. Los gestos donde Maestro brilla y donde Appium sufre.
Cuando los publique, los suscriptores del newsletter se enteran primero. Como siempre.
Escribime. Leo todas las respuestas, y los bloqueos reales me sirven para escribir las próximas guías de cualquier tema. Tu pregunta puede destrabarle el camino a 100 QAs más.