Files

243 lines
8.5 KiB
Bash

#!/usr/bin/env bash
# run_kotlin_app_tests — Pipeline e2e completo de testing app Kotlin:
# unit JVM + screenshot Roborazzi + build APK + instrumented Compose en emulador.
#
# USO:
# bash run_kotlin_app_tests.sh <project_dir> [avd_name] [--skip-emulator] [--no-stop]
#
# ARGUMENTOS:
# project_dir Raiz del proyecto Android (debe contener gradlew). Obligatorio.
# avd_name Nombre del AVD para instrumented tests. Default: Medium_Phone_API_35.
# --skip-emulator Saltar instrumented tests (solo unit + screenshot + build).
# --no-stop No parar el emulador al finalizar (util en desarrollo iterativo).
#
# EXIT CODES:
# 0 Todos los tests pasan.
# 1 Unit tests fallaron.
# 2 Screenshot tests fallaron.
# 3 Build APK fallado.
# 4 AVD no encontrado.
# 5 Instrumented tests fallaron.
#
# EJEMPLO:
# bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app
# bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app Pixel_7_API_34
# bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app --skip-emulator
# bash bash/functions/pipelines/run_kotlin_app_tests.sh apps/my_app Medium_Phone_API_35 --no-stop
set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REGISTRY_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
# ---------------------------------------------------------------------------
# Parseo de argumentos
# ---------------------------------------------------------------------------
PROJECT_DIR="${1:-}"
AVD_NAME="Medium_Phone_API_35"
SKIP_EMULATOR=false
NO_STOP=false
# Primer argumento posicional es project_dir; el resto puede ser flags o avd_name.
shift || true
for arg in "$@"; do
case "$arg" in
--skip-emulator) SKIP_EMULATOR=true ;;
--no-stop) NO_STOP=true ;;
--*)
echo "[run_kotlin_app_tests] ERROR: flag desconocido: $arg" >&2
echo "USO: $0 <project_dir> [avd_name] [--skip-emulator] [--no-stop]" >&2
exit 1
;;
*) AVD_NAME="$arg" ;;
esac
done
if [[ -z "$PROJECT_DIR" ]]; then
echo "[run_kotlin_app_tests] ERROR: project_dir es obligatorio." >&2
echo "USO: $0 <project_dir> [avd_name] [--skip-emulator] [--no-stop]" >&2
exit 1
fi
# Resolver path absoluto
if [[ "$PROJECT_DIR" != /* ]]; then
PROJECT_DIR="$(pwd)/$PROJECT_DIR"
fi
# ---------------------------------------------------------------------------
# Validacion inicial
# ---------------------------------------------------------------------------
if [[ ! -f "$PROJECT_DIR/gradlew" ]]; then
echo "[run_kotlin_app_tests] ERROR: no se encontro gradlew en $PROJECT_DIR" >&2
exit 1
fi
echo ""
echo "======================================================================"
echo " run_kotlin_app_tests"
echo "======================================================================"
echo " project_dir : $PROJECT_DIR"
echo " avd_name : $AVD_NAME"
echo " skip_emulator : $SKIP_EMULATOR"
echo " no_stop : $NO_STOP"
echo "======================================================================"
echo ""
# ---------------------------------------------------------------------------
# Tabla de resultados acumulada
# ---------------------------------------------------------------------------
# Arrays paralelos: nombre, status, tiempo
STEP_NAMES=()
STEP_STATUS=()
STEP_TIMES=()
record_step() {
local name="$1" status="$2" elapsed="$3"
STEP_NAMES+=("$name")
STEP_STATUS+=("$status")
STEP_TIMES+=("${elapsed}s")
}
print_summary() {
echo ""
echo "======================================================================"
echo " RESUMEN"
printf " %-30s %-6s %s\n" "STEP" "STATUS" "TIEMPO"
echo " ------------------------------ ------ ------"
for i in "${!STEP_NAMES[@]}"; do
printf " %-30s %-6s %s\n" "${STEP_NAMES[$i]}" "${STEP_STATUS[$i]}" "${STEP_TIMES[$i]}"
done
echo "======================================================================"
echo ""
}
# ---------------------------------------------------------------------------
# Paso 1: Unit tests (JVM)
# ---------------------------------------------------------------------------
echo "[run_kotlin_app_tests] [1/4] Unit tests (JVM)..."
T_START=$SECONDS
if bash "$REGISTRY_ROOT/bash/functions/infra/gradle_unit_test.sh" "$PROJECT_DIR"; then
record_step "unit_tests" "OK" $((SECONDS - T_START))
echo "[run_kotlin_app_tests] Unit tests: OK"
else
record_step "unit_tests" "FAIL" $((SECONDS - T_START))
print_summary
echo "[run_kotlin_app_tests] ERROR: unit tests fallaron." >&2
exit 1
fi
# ---------------------------------------------------------------------------
# Paso 2: Screenshot tests (Roborazzi, JVM)
# ---------------------------------------------------------------------------
echo ""
echo "[run_kotlin_app_tests] [2/4] Screenshot tests (Roborazzi, JVM)..."
T_START=$SECONDS
if bash "$REGISTRY_ROOT/bash/functions/infra/gradle_screenshot_test.sh" "$PROJECT_DIR"; then
record_step "screenshot_tests" "OK" $((SECONDS - T_START))
echo "[run_kotlin_app_tests] Screenshot tests: OK"
else
record_step "screenshot_tests" "FAIL" $((SECONDS - T_START))
print_summary
echo "[run_kotlin_app_tests] ERROR: screenshot tests fallaron." >&2
exit 2
fi
# ---------------------------------------------------------------------------
# Paso 3: Build APK debug
# ---------------------------------------------------------------------------
echo ""
echo "[run_kotlin_app_tests] [3/4] Build APK debug..."
T_START=$SECONDS
if bash "$REGISTRY_ROOT/bash/functions/infra/gradle_assemble_debug.sh" "$PROJECT_DIR"; then
record_step "assemble_debug" "OK" $((SECONDS - T_START))
echo "[run_kotlin_app_tests] Build APK: OK"
else
record_step "assemble_debug" "FAIL" $((SECONDS - T_START))
print_summary
echo "[run_kotlin_app_tests] ERROR: build APK fallado." >&2
exit 3
fi
# ---------------------------------------------------------------------------
# Paso 4: Instrumented tests (emulador)
# ---------------------------------------------------------------------------
if [[ "$SKIP_EMULATOR" == "true" ]]; then
record_step "instrumented_tests" "SKIP" 0
print_summary
echo "[run_kotlin_app_tests] --skip-emulator activo. Pipeline completo (sin instrumented)."
exit 0
fi
echo ""
echo "[run_kotlin_app_tests] [4/4] Instrumented tests en emulador '$AVD_NAME'..."
# Source adb_wsl para resolver $ADB y helpers de dispositivo
# shellcheck source=../infra/adb_wsl.sh
source "$REGISTRY_ROOT/bash/functions/infra/adb_wsl.sh"
# Verificar que el AVD existe
echo "[run_kotlin_app_tests] Verificando AVD '$AVD_NAME'..."
if ! bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_list.sh" | grep -qx "$AVD_NAME"; then
record_step "emulator_check" "FAIL" 0
record_step "instrumented_tests" "SKIP" 0
print_summary
echo "[run_kotlin_app_tests] ERROR: AVD '$AVD_NAME' no encontrado." >&2
echo " AVDs disponibles:" >&2
bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_list.sh" | sed 's/^/ /' >&2
exit 4
fi
record_step "emulator_check" "OK" 0
# Arrancar emulador (idempotente)
echo "[run_kotlin_app_tests] Arrancando emulador '$AVD_NAME' (idempotente)..."
T_START=$SECONDS
if ! bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_start.sh" "$AVD_NAME"; then
record_step "emulator_start" "FAIL" $((SECONDS - T_START))
print_summary
echo "[run_kotlin_app_tests] ERROR: no se pudo arrancar el emulador." >&2
exit 4
fi
record_step "emulator_start" "OK" $((SECONDS - T_START))
# Correr instrumented tests
echo "[run_kotlin_app_tests] Corriendo instrumented tests..."
T_START=$SECONDS
INSTRUMENTED_EXIT=0
bash "$REGISTRY_ROOT/bash/functions/infra/gradle_instrumented_test.sh" "$PROJECT_DIR" || INSTRUMENTED_EXIT=$?
if [[ $INSTRUMENTED_EXIT -eq 0 ]]; then
record_step "instrumented_tests" "OK" $((SECONDS - T_START))
echo "[run_kotlin_app_tests] Instrumented tests: OK"
else
record_step "instrumented_tests" "FAIL" $((SECONDS - T_START))
fi
# Parar emulador (salvo --no-stop)
if [[ "$NO_STOP" == "false" ]]; then
echo "[run_kotlin_app_tests] Parando emulador..."
T_START=$SECONDS
bash "$REGISTRY_ROOT/bash/functions/infra/android_emulator_stop.sh" || true
record_step "emulator_stop" "OK" $((SECONDS - T_START))
else
record_step "emulator_stop" "SKIP" 0
echo "[run_kotlin_app_tests] --no-stop activo: emulador sigue corriendo."
fi
print_summary
if [[ $INSTRUMENTED_EXIT -ne 0 ]]; then
echo "[run_kotlin_app_tests] ERROR: instrumented tests fallaron." >&2
exit 5
fi
echo "[run_kotlin_app_tests] Pipeline e2e completado con exito."
exit 0