Las plataformas Mobile Backend as a Service (MBaaS) aceleran el desarrollo proporcionando infraestructura backend lista para usar. Sin embargo, probar integraciones MBaaS requiere estrategias diferentes al testing tradicional de APIs. Esta guía cubre testing de Firebase, AWS Amplify y Supabase en aplicaciones móviles.

Comprendiendo los Desafíos del Testing MBaaS

Características Únicas

CaracterísticaAPI TradicionalMBaaS
AutenticaciónEndpoints personalizadosGestionada (OAuth, Social Login)
Sincronización DatosRequest/ResponseListeners en tiempo real
Modo OfflineImplementación manualCaché integrado
Almacenamiento ArchivosEndpoints upload personalizadosBuckets de storage gestionados
Notificaciones PushServicios tercerosMensajería integrada
Enfoque TestingHTTP mockingSDK mocking + Emuladores

Al probar plataformas MBaaS, las pruebas de rendimiento de API se vuelven cruciales para monitorear cuotas, latencia y eficiencia de sincronización en tiempo real.

Firebase Testing

Firebase Local Emulator Suite

Configuración:

# Instalar Firebase CLI
npm install -g firebase-tools

# Inicializar Firebase en proyecto
firebase init

# Iniciar emuladores
firebase emulators:start

Android Firebase Testing

Firestore Test:

import com.google.firebase.firestore.FirebaseFirestore

class UserRepositoryTest {
    private lateinit var firestore: FirebaseFirestore

    @Before
    fun setUp() {
        firestore = FirebaseFirestore.getInstance().apply {
            useEmulator("10.0.2.2", 8080)
            firestoreSettings = FirebaseFirestoreSettings.Builder()
                .setPersistenceEnabled(false)
                .build()
        }
    }

    @Test
    fun testCreateUser() = runTest {
        val user = User(
            id = "test-user-1",
            username = "usuarioprueba",
            email = "test@ejemplo.com"
        )

        userRepository.createUser(user)

        val snapshot = firestore.collection("users")
            .document("test-user-1")
            .get()
            .await()

        assertTrue(snapshot.exists())
        assertEquals("usuarioprueba", snapshot.getString("username"))
    }

    @Test
    fun testRealtimeUserUpdates() = runTest {
        val updates = mutableListOf<User>()

        val job = launch {
            userRepository.observeUser("test-user-1").collect { user ->
                user?.let { updates.add(it) }
            }
        }

        val user = User(id = "test-user-1", username = "original")
        userRepository.createUser(user)
        delay(100)

        userRepository.updateUsername("test-user-1", "actualizado")
        delay(100)

        job.cancel()

        assertEquals(2, updates.size)
        assertEquals("original", updates[0].username)
        assertEquals("actualizado", updates[1].username)
    }

    @Test
    fun testOfflineMode() = runTest {
        firestore.firestoreSettings = FirebaseFirestoreSettings.Builder()
            .setPersistenceEnabled(true)
            .build()

        val user = User(id = "offline-user", username = "offline-test")
        userRepository.createUser(user)

        // Simular modo offline
        firestore.disableNetwork().await()

        // Leer desde caché
        val cachedUser = userRepository.getUser("offline-user")
        assertNotNull(cachedUser)
        assertEquals("offline-test", cachedUser?.username)

        // Escribir mientras offline
        userRepository.updateUsername("offline-user", "actualizado-offline")

        // Re-habilitar red
        firestore.enableNetwork().await()
        delay(500)

        // Verificar que escritura offline se sincronizó
        val syncedUser = userRepository.getUser("offline-user")
        assertEquals("actualizado-offline", syncedUser?.username)
    }
}

Comprender las pruebas móviles para iOS y Android es esencial al implementar soluciones MBaaS en diferentes entornos móviles.

AWS Amplify Testing

Amplify Mock Backend

Configuración:

# Instalar Amplify CLI
npm install -g @aws-amplify/cli

# Inicializar Amplify
amplify init

# Añadir API
amplify add api

# Iniciar mock server
amplify mock api

Android Amplify Testing

import com.amplifyframework.api.graphql.model.ModelMutation
import com.amplifyframework.datastore.generated.model.Todo

class TodoRepositoryTest {

    @Test
    fun testCreateTodo() = runTest {
        val todo = Todo.builder()
            .name("Test Todo")
            .description("Probando Amplify")
            .build()

        val result = todoRepository.createTodo(todo)

        assertNotNull(result)
        assertEquals("Test Todo", result.name)
    }

    @Test
    fun testQueryTodos() = runTest {
        val todo1 = Todo.builder().name("Todo 1").build()
        val todo2 = Todo.builder().name("Todo 2").build()

        todoRepository.createTodo(todo1)
        todoRepository.createTodo(todo2)

        val todos = todoRepository.getAllTodos()

        assertTrue(todos.size >= 2)
        assertTrue(todos.any { it.name == "Todo 1" })
    }
}

Supabase Testing

Supabase Local Development

Configuración:

# Instalar Supabase CLI
npm install -g supabase

# Inicializar Supabase
supabase init

# Iniciar Supabase local
supabase start

Android Supabase Testing

import io.github.jan.supabase.postgrest.from

class UserRepositorySupabaseTest {

    private val supabase = createTestSupabaseClient()

    @Test
    fun testCreateUser() = runTest {
        val user = UserDto(
            username = "usuarioprueba",
            email = "test@ejemplo.com"
        )

        val created = supabase.from("users")
            .insert(user)
            .decodeSingle<UserDto>()

        assertEquals("usuarioprueba", created.username)
        assertNotNull(created.id)
    }

    @Test
    fun testRealtimeSubscription() = runTest {
        val updates = mutableListOf<UserDto>()

        val channel = supabase.realtime.createChannel("users")
        channel.postgresChangeFlow<PostgresAction.Insert>(
            schema = "public",
            table = "users"
        ).onEach { change ->
            updates.add(change.record)
        }.launchIn(this)

        channel.subscribe()
        delay(200)

        supabase.from("users").insert(
            UserDto(username = "realtime-user", email = "rt@ejemplo.com")
        )

        delay(500)
        channel.unsubscribe()

        assertTrue(updates.any { it.username == "realtime-user" })
    }
}

Mejores Prácticas de Testing

1. Aislar Datos de Prueba

@Before
fun setUp() {
    val testCollectionPrefix = "test_${UUID.randomUUID()}_"
    firestore.collection("${testCollectionPrefix}users")
}

@After
fun tearDown() {
    deleteTestCollections()
}

2. Mockear Dependencias Externas

class UserRepository(
    private val firestore: FirebaseFirestore,
    private val analytics: Analytics = FirebaseAnalytics.getInstance()
)

// En tests, inyectar analytics mock
val mockAnalytics = mock<Analytics>()
val repository = UserRepository(firestore, mockAnalytics)

3. Probar Transiciones Offline/Online

@Test
fun testOnlineOfflineTransition() = runTest {
    val user = userRepository.getUser("user-1")
    assertNotNull(user)

    firestore.disableNetwork().await()

    val cachedUser = userRepository.getUser("user-1")
    assertEquals(user, cachedUser)

    firestore.enableNetwork().await()

    val syncedUser = userRepository.getUser("user-1")
    assertEquals(user, syncedUser)
}

La seguridad es primordial al trabajar con autenticación y almacenamiento de datos en plataformas MBaaS. Implementar prácticas de pruebas de seguridad móvil garantiza que tus servicios backend estén protegidos contra vulnerabilidades comunes.

Integración CI/CD

GitHub Actions con Firebase Emulators

name: MBaaS Tests

on: [push, pull_request]

jobs:
  firebase-tests:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Install Firebase CLI
        run: npm install -g firebase-tools

      - name: Start Firebase Emulators
        run: firebase emulators:start --only firestore,auth &

      - name: Run Android Tests
        run: ./gradlew connectedAndroidTest

Conclusión

El testing MBaaS requiere:

  • Emuladores Locales: Firebase, Amplify mock, Supabase local
  • Testing Real-time: Suscripciones, listeners, sincronización de datos
  • Testing Offline: Validación de caché, verificación de sync
  • Monitoreo de Rendimiento: Seguimiento de cuotas, optimización

Estrategia de Testing:

  1. Tests unitarios con SDKs mockeados
  2. Tests de integración con emuladores
  3. Tests E2E con instancias MBaaS de staging
  4. Monitorear métricas de producción

Las plataformas MBaaS aceleran el desarrollo pero requieren testing disciplinado para asegurar confiabilidad, soporte offline y optimización de costos.