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ística | API Tradicional | MBaaS |
---|---|---|
Autenticación | Endpoints personalizados | Gestionada (OAuth, Social Login) |
Sincronización Datos | Request/Response | Listeners en tiempo real |
Modo Offline | Implementación manual | Caché integrado |
Almacenamiento Archivos | Endpoints upload personalizados | Buckets de storage gestionados |
Notificaciones Push | Servicios terceros | Mensajería integrada |
Enfoque Testing | HTTP mocking | SDK 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:
- Tests unitarios con SDKs mockeados
- Tests de integración con emuladores
- Tests E2E con instancias MBaaS de staging
- 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.