Las aplicaciones móviles deben funcionar confiablemente en varias condiciones de red. Probar conexiones lentas, conectividad intermitente y escenarios offline asegura experiencias de usuario robustas. La confiabilidad de red impacta directamente el rendimiento de aplicaciones móviles, haciendo la simulación de condiciones esencial para QA.
Para una cobertura completa de testing móvil, revisa nuestra guía de Mobile Testing 2025: iOS, Android y Más Allá. Las pruebas de rendimiento de API también deben considerar condiciones de red variables. Integrar estas pruebas en tu estrategia de automatización y en testing continuo en DevOps asegura cobertura consistente.
Android Simulación de Red
Usando Interceptores OkHttp
class NetworkConditionInterceptor(
private val delayMs: Long = 0,
private val packetLossRate: Double = 0.0,
private val bandwidthBytesPerSecond: Long = Long.MAX_VALUE
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
// Simular latencia
if (delayMs > 0) {
Thread.sleep(delayMs)
}
// Simular pérdida de paquetes
if (Random.nextDouble() < packetLossRate) {
throw SocketTimeoutException("Pérdida de paquetes simulada")
}
return chain.proceed(chain.request())
}
}
// Uso
val client = OkHttpClient.Builder()
.addInterceptor(
NetworkConditionInterceptor(
delayMs = 500,
packetLossRate = 0.1,
bandwidthBytesPerSecond = 128_000
)
)
.build()
Testing Diferentes Condiciones
@Test
fun testSlowConnection() = runTest {
val slowClient = OkHttpClient.Builder()
.addInterceptor(NetworkConditionInterceptor(
delayMs = 2000,
bandwidthBytesPerSecond = 50_000
))
.build()
val startTime = System.currentTimeMillis()
val response = apiService.getUsers()
val duration = System.currentTimeMillis() - startTime
assertTrue(duration >= 2000)
}
@Test
fun testPacketLoss() = runTest {
val unreliableClient = OkHttpClient.Builder()
.addInterceptor(NetworkConditionInterceptor(
packetLossRate = 0.5
))
.build()
var failureCount = 0
repeat(100) {
try {
apiService.getUsers()
} catch (e: SocketTimeoutException) {
failureCount++
}
}
assertTrue(failureCount in 40..60)
}
Testing Modo Offline
El testing de condiciones de red es crucial para testing móvil en 2025, donde apps iOS y Android enfrentan diversos escenarios de conectividad.
@Test
fun testOfflineDataAccess() = runTest {
val offlineClient = OkHttpClient.Builder()
.addInterceptor { chain ->
throw UnknownHostException("Sin red disponible")
}
.build()
val repository = UserRepository(offlineClient)
val users = repository.getUsers()
assertNotNull(users)
verify { localDatabase.getUsers() }
}
@Test
fun testOfflineWriteQueueing() = runTest {
syncManager.setNetworkAvailable(false)
val newUser = User(id = "123", name = "Usuario Test")
syncManager.queueCreateUser(newUser)
val pending = syncManager.getPendingOperations()
assertEquals(1, pending.size)
syncManager.setNetworkAvailable(true)
delay(1000)
assertEquals(0, syncManager.getPendingOperations().size)
}
Implementar patrones offline-first requiere estrategia de caching API para móviles, asegurando disponibilidad de datos independientemente del estado de red.
Lógica de Retry
Probar mecanismos de retry bajo condiciones de red pobres es esencial para testing de rendimiento API, asegurando resiliencia contra fallos transitorios.
class RetryInterceptor(
private val maxRetries: Int = 3,
private val initialDelay: Long = 1000
) : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var attempt = 0
var delay = initialDelay
while (attempt <= maxRetries) {
try {
return chain.proceed(chain.request())
} catch (e: IOException) {
attempt++
if (attempt > maxRetries) throw e
Thread.sleep(delay)
delay *= 2
}
}
throw IOException("Reintentos máximos excedidos")
}
}
@Test
fun testRetryLogic() = runTest {
var attemptCount = 0
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
attemptCount++
if (attemptCount < 3) {
throw SocketTimeoutException("Fallo simulado")
}
chain.proceed(chain.request())
}
.addInterceptor(RetryInterceptor(maxRetries = 3))
.build()
val response = client.newCall(request).execute()
assertEquals(3, attemptCount)
assertTrue(response.isSuccessful)
}
Mejores Prácticas
- Prueba con perfiles de red realistas - 3G, 4G, WiFi
- Implementa lógica retry con backoff exponencial - Maneja fallos transitorios
- Usa arquitectura offline-first - Cachea datos localmente
- Prueba transiciones de red - WiFi ↔ celular, online ↔ offline
- Monitorea rendimiento de red - Rastrea latencia, throughput
Conclusión
El testing de condiciones de red asegura:
- Degradación graceful en redes lentas
- Funcionalidad offline
- Mecanismos de retry apropiados
- Consistencia de datos en estados de red
Probar varias condiciones de red previene experiencias de usuario pobres y pérdida de datos.
Ver También
- Mobile Testing 2025: iOS, Android y Más Allá - Guía completa de testing móvil moderno
- Pruebas de Rendimiento de Aplicaciones Móviles - Métricas y mejores prácticas de rendimiento
- Pruebas de Rendimiento de API - Testing de APIs bajo condiciones de red variables
- Estrategia de Automatización de Pruebas - Integrar testing de condiciones de red
- Testing Continuo en DevOps - Automatizar pruebas de red en pipelines CI/CD