Docs de Autonomy
Móvil

Builds móviles

Compila un APK de Android y súbelo a un entorno o envíalo desde el CI con la API.

Las ejecuciones móviles necesitan un build de tu app. Ponlo en un objetivo del entorno para reutilizarlo en todas las ejecuciones hasta la siguiente versión, o súbelo desde el CI e inicia ejecuciones con él directamente.

Qué subir

VariableRequiredDescription
iOS .app (.zip, .tgz, .tar.gz)NoBuild de simulador del bundle .app, archivado con el .app en la raíz del archivo.
Android .apkNoPaquete de Android estándar.
Android .aabNoAndroid App Bundle.

Para iOS (próximamente), Autonomy necesita un build de simulador, porque las ejecuciones usan simuladores de iOS. Un .ipa firmado y compilado para dispositivos no puede ejecutarse. Para Android, funcionan tanto .apk como .aab; las ejecuciones instalan el build en un emulador y lo abren por su nombre de paquete. Los builds móviles pueden ocupar hasta 512 MB. Cada subida pasa un control de seguridad antes de que una ejecución pueda usarla.

Compilar para el simulador de iOS

Las pruebas en iOS llegarán pronto. Guarda esto para cuando estén disponibles. Hasta entonces, Autonomy no inicia ejecuciones en iOS.

Para un proyecto de Xcode, compila con xcodebuild:

Compilar el .app para el simulador de iOSbash
xcodebuild -workspace ios/MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-sdk iphonesimulator \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath ios/build \
CODE_SIGNING_ALLOWED=NO \
build

El bundle queda en ios/build/Build/Products/Release-iphonesimulator/MyApp.app. En proyectos de Expo o React Native, ejecuta primero npx expo prebuild --platform ios y después el mismo comando xcodebuild contra el workspace generado.

Comprime el bundle en zip antes de subirlo, con el .app en la raíz del archivo. -y conserva los enlaces simbólicos.

Comprimir el bundle .appbash
cd ios/build/Build/Products/Release-iphonesimulator
zip -qry MyApp.app.zip MyApp.app

Compilar para Android

Para un proyecto de Android, compila un APK de debug. Los APK de debug se instalan en emuladores sin firma adicional.

Compilar el APK de debugbash
cd android
./gradlew assembleDebug

El APK queda en android/app/build/outputs/apk/debug/app-debug.apk. En proyectos de Expo o React Native, ejecuta primero npx expo prebuild --platform android y después el mismo comando de Gradle contra el proyecto generado.

Para un App Bundle, ejecuta ./gradlew bundleDebug y toma el .aab de android/app/build/outputs/bundle/debug/.

Subir desde el panel

  1. Abre el proyecto, pulsa Environments y abre el entorno. Los propietarios y administradores pueden editar entornos.
  2. En el objetivo iOS o Android, elige Upload y suelta el zip del .app, el .apk o el .aab, o haz clic para buscarlo.
  3. Espera a "Uploaded and scanned" y guarda el entorno.
  4. Ejecuta una vez un caso de prueba en ese entorno para confirmar que el build se abre y que se puede alcanzar el primer paso.

Para usar un build que tu CI ya publica, elige URL y pega un enlace de descarga directo. Las ejecuciones usan el build al que apuntaba el enlace cuando lo guardaste. Cuando tu CI publique un build nuevo en el mismo enlace, vuelve a guardar el enlace o sube el build desde CI como se explica abajo. Consulta Entornos.

Subir con la API

Usa la API desde el CI cuando el build sea nuevo para este pipeline y no deba sustituir al build del entorno. Son tres llamadas, y después el ID de almacenamiento del build va a run.trigger. Autentícate con una clave de API de la organización que empiece por aut_, de Organization → API keys (propietarios y administradores).

  1. POST /api/artifacts/upload-url con platform (ios o android), fileName, contentType y declaredBytes (el tamaño del archivo en bytes). La respuesta tiene uploadUrl, storageId, method ("PUT"), intentId y expiresAt.
  2. Haz PUT del archivo a uploadUrl con el mismo Content-Type.
  3. POST /api/artifacts/scan con storageId e intentId. Inicia ejecuciones solo cuando status sea "clean"; si no, findings indica qué estaba mal.
Subir un build de simulador de iOSbash
set -euo pipefail
API=https://api.autonomyqa.com
FILE=ios/build/Build/Products/Release-iphonesimulator/MyApp.app.zip

UPLOAD=$(curl -fsS -X POST "$API/api/artifacts/upload-url" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --argjson bytes "$(wc -c < "$FILE" | tr -d ' ')" \
  '{platform: "ios", fileName: "MyApp.app.zip", contentType: "application/zip", declaredBytes: $bytes}')")
STORAGE_ID=$(jq -r '.storageId' <<< "$UPLOAD")
INTENT_ID=$(jq -r '.intentId' <<< "$UPLOAD")

curl -fsS -X PUT "$(jq -r '.uploadUrl' <<< "$UPLOAD")" \
-H "Content-Type: application/zip" \
--data-binary "@$FILE"

SCAN=$(curl -fsS -X POST "$API/api/artifacts/scan" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg s "$STORAGE_ID" --arg i "$INTENT_ID" '{storageId: $s, intentId: $i}')")
jq -e '.status == "clean"' <<< "$SCAN" > /dev/null

Después inicia las ejecuciones con POST /api/v1/run.trigger. Indica exactamente uno de testPlanId (un plan de pruebas: una ejecución por caso de prueba) o testCaseId (un caso de prueba), el build como objetivo explícito y un idempotencyKey en el cuerpo. Reintentar con la misma clave devuelve las mismas ejecuciones en lugar de iniciar otras nuevas.

Iniciar ejecuciones con el build subidobash
TRIGGER=$(curl -fsS -X POST "$API/api/v1/run.trigger" \
-H "Authorization: Bearer $AUTONOMY_API_KEY" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg plan "$AUTONOMY_TEST_PLAN_ID" --arg s "$STORAGE_ID" \
  --arg key "my-ci:$BUILD_ID:ios" \
  '{
    testPlanId: $plan,
    platforms: ["ios"],
    targets: { ios: { bundleId: "com.example.MyApp", storageId: $s, sourceMode: "upload", fileName: "MyApp.app.zip" } },
    branch: "main",
    deployment: { provider: "my-ci", branch: "main", commitSha: "abc123" },
    idempotencyKey: $key
  }')")
jq -r '.runIds[]' <<< "$TRIGGER"

La respuesta es { runIds, planGroupRunId?, environment? }. Para Android, envía platform: "android" y contentType: "application/vnd.android.package-archive", e inicia las ejecuciones con targets.android y packageName en lugar de bundleId.

Para ejecutar contra un entorno guardado, envía environmentSlug en lugar de targets: la ejecución usa el build y los valores de ese entorno. Un objetivo explícito no tiene entorno, así que los pasos que usan {{env.NAME}} terminan como Couldn't start. Si tu CI ya te da un enlace HTTPS al build, omite la subida y envía artifactUrl con sourceMode: "url".

Seguir las ejecuciones

Llama a POST /api/v1/run.get con runId, el cursor de la respuesta anterior y waitMs de hasta 25000. Cada llamada espera hasta que la ejecución cambia; timedOut: true solo significa que todavía no ha cambiado nada. Para cuando status sea passed, failed, couldnt_start o cancelled.

Para condicionar un pipeline, dalo por superado solo cuando todas las ejecuciones sean passed (una superada con reintento cuenta). failed lo hace fallar; abre la ejecución para ver qué paso falló y por qué. couldnt_start también lo hace fallar, pero significa que no se pudo probar el entorno, por ejemplo porque el build no se instaló, no que tu app esté rota.

Las recetas de CI agrupan todo esto (subir, iniciar y seguir) en un solo script .ci/autonomy.sh: consulta GitHub Actions, GitLab CI, Jenkins, Bitrise y CircleCI. Los campos y los errores están en la referencia de la API y en Ejecuciones y evidencia.

Limitaciones

  • iOS solo se ejecuta en simuladores. La cámara, Face ID, Touch ID y cualquier flujo que necesite un build firmado para dispositivo no funcionan.
  • Android se ejecuta en emuladores. Las funciones que dependen del hardware, como NFC, la huella dactilar y una cámara real, no están disponibles.

Solución de problemas

Se rechaza la subida de iOS

Comprueba que el build usó -sdk iphonesimulator y un destino de simulador, y que subiste un .zip, .tgz o .tar.gz con el .app dentro. Un build para iphoneos es un build de dispositivo.

Se rechaza la subida de Android

Solo se aceptan archivos .apk y .aab.

La petición de la URL de subida devuelve 400

declaredBytes (un número) y contentType son obligatorios. La petición del escaneo necesita tanto storageId como intentId de la respuesta de la URL de subida.

La ejecución usó un build anterior

Una ejecución con environmentSlug usa el build del entorno, no el que acabas de subir. Envía el build nuevo como objetivo explícito o actualiza antes el objetivo del entorno.

¿No lo encontraste?

On this page