Las condiciones de red impactan profundamente la experiencia del usuario de maneras que los entornos de desarrollo nunca replican. Según un estudio de Google, el 53% de los usuarios móviles abandonan sitios que tardan más de 3 segundos en cargar. Según investigación de Akamai, las páginas que experimentan incluso breves interrupciones de red ven tasas de rebote un 40% más altas. Probar bajo condiciones de red realistas no es opcional para equipos que apuntan a mercados globales: debes verificar cómo se comporta tu aplicación a diferentes anchos de banda (2G, 3G, 4G, WiFi), latencias y tasas de pérdida de paquetes. Esta guía cubre herramientas de simulación de condiciones de red.
TL;DR: El testing de condiciones de red simula conectividad del mundo real para apps web y móviles. Usa Chrome DevTools para testing en navegador, tc netem (Linux) para simulación a nivel OS y Charles Proxy/Proxyman para throttling de tráfico móvil. Prueba mínimamente: perfiles Fast 3G, Slow 3G y 2G.
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)
}
“Most teams test their apps on localhost with perfect network conditions and wonder why mobile users complain. Network simulation is not optional — it’s the only way to know how your app actually performs in the real world.” — Yuri Kan, Senior QA Lead
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
Recursos Oficiales
FAQ
¿Qué perfiles de red debo probar?
Perfiles estándar: WiFi (50+ Mbps, 5ms latencia), Fast 4G/LTE (10 Mbps, 20ms), Regular 4G (4 Mbps, 30ms), Fast 3G (1.5 Mbps, 40ms), Slow 3G (400 Kbps, 400ms), 2G (250 Kbps, 750ms) y Offline. Prioriza perfiles que coincidan con la demografía de tus usuarios.
¿Cómo simulo condiciones de red para testing móvil?
Para iOS: usa Xcode Network Link Conditioner. Para Android: usa opciones de desarrollador > Simular condiciones de red, o tc netem vía adb en dispositivos rooteados. Para ambas plataformas: usa una herramienta proxy como Charles Proxy para limitar todo el tráfico.
¿Cómo pruebo el modo offline y la degradación elegante?
Prueba: offline completo, transición de online a offline durante una operación, conectividad parcial (pérdida de paquetes intermitente) y fallos de DNS. Verifica: los datos en caché se sirven offline, las operaciones pendientes se encolan y se reanudan al reconectarse.
¿Cómo simulo pérdida de paquetes en testing?
Linux tc netem: ’tc qdisc add dev eth0 root netem loss 5%’ simula 5% de pérdida. El perfil personalizado de Chrome DevTools soporta simulación de pérdida de paquetes. La configuración de Charles Proxy Throttle incluye pérdida de paquetes.
See Also
- Testing de Certificate Pinning en Aplicaciones Móviles: Validación SSL/TLS, Protección MITM y Rotación de Pins - Prueba certificate pinning: validación SSL/TLS, protección MITM,…
- Estrategia de Caching de Respuestas API para Aplicaciones Móviles: Políticas de Caché, Soporte Offline y Estrategias de Sincronización - Domina el caching de API móvil: estrategias cache-first vs…
- Appium 2.0: Nueva Arquitectura e Integración en la Nube para Testing Mobile Moderno - Explora la arquitectura revolucionaria de Appium 2.0, su…
- Testing de WebSocket para Aplicaciones Móviles en Tiempo Real: Estabilidad de Conexión, Orden de Mensajes y Optimización de Batería - Prueba WebSocket en apps móviles: estabilidad conexión,…
