Pruebas de carga para aplicaciones en tiempo real: por qué las videollamadas necesitan más que JMeter
La mayoría de las pruebas de carga asumen una forma sencilla: enviar una petición, recibir una respuesta, medir cuánto ha tardado, repetirlo miles de veces. Esa forma se parece lo suficiente a la realidad para la mayoría de las aplicaciones reales. No se parece lo suficiente para una aplicación en tiempo real. Una entrada anterior describía una plataforma masiva de distribución de vídeo en directo construida sobre ERTSA, nuestra arquitectura serverless elástica; probar algo así es un problema genuinamente distinto al de probar una API, y las videollamadas son un buen caso de estudio para explicar por qué.
El estado actual de las pruebas: tres mundos distintos
Las pruebas de carga tradicionales para aplicaciones web son un problema maduro y bien resuelto. Herramientas como JMeter, k6, Gatling, Locust y Artillery repiten peticiones a nivel de protocolo de forma barata, miles o millones de ellas, desde una sola máquina. Eso funciona porque una petición/respuesta HTTP es breve y sin estado; simularla no requiere nada parecido a un cliente real.
Las pruebas funcionales end-to-end (E2E) son una disciplina distinta: demostrar que un flujo completo de usuario funciona de verdad, no cómo se comporta bajo carga. Frameworks como Selenium, Puppeteer y Cucumber manejan un navegador real a través de un flujo real completo, paso a paso, y la mayoría de los equipos ya tienen una suite escrita en alguno de ellos. Herramientas de scripting HTTP más antiguas como Badboy cubrían un terreno parecido para casos más sencillos, aunque el campo ha avanzado desde entonces; el módulo browser de k6, de Grafana es un ejemplo más actual que merece la pena conocer, y, de forma reveladora, la propia documentación de Grafana recomienda un enfoque híbrido, un puñado de usuarios virtuales con navegador real junto a un número mucho mayor de usuarios virtuales a nivel de protocolo, porque un VU con navegador cuesta aproximadamente 10 veces más que un VU de protocolo a cualquier escala real. Es la propia industria reconociendo exactamente el hueco del que trata esta entrada.
Las pruebas específicas para WebRTC son las que más se acercan a lo que necesita de verdad un enfoque como el nuestro, y por eso merece la pena dejarlas para el final. Una videollamada es una conexión bidireccional de larga duración con un stack real de ICE/DTLS/SRTP codificando y decodificando medios reales, no un par petición/respuesta, así que ninguno de los dos mundos anteriores la prueba bien por sí solo. Las herramientas de pruebas para WebRTC que existen se dividen a grandes rasgos en dos grupos: algunas siguen un enfoque de API, ejercitando los endpoints de señalización o gestión de sesión de una plataforma sin un stack de medios real detrás; otras toman el enfoque de pruebas funcionales y lo extienden hacia la carga, como hace la herramienta de pruebas de carga de OpenVidu, que maneja instancias reales de Chrome y Firefox mediante Selenium en lugar de simular paquetes. Ese segundo grupo es el pariente más cercano de lo que trata esta entrada, y es también donde aparece el verdadero hueco: coordinar un número grande de esas instancias con navegador real, y recoger información rica del lado del cliente de cada una de ellas, no es algo que estas herramientas extiendan de forma masiva. Esa fidelidad también tiene un coste real de cualquier forma: un estudio de 2022 sobre pruebas de carga para WebRTC encontró que las alternativas sin navegador, que aproximan el comportamiento del stack de WebRTC sin lanzar un motor de navegador completo, reducen ese coste en torno a un 96% frente al enfoque tradicional con navegador real, a cambio de algo de fidelidad; una decisión que merece la pena nombrar con honestidad en lugar de asumir que un enfoque es sencillamente el correcto.
Cuatro formas de hacer pruebas de carga a algo así
- Simulación a nivel de protocolo. Barata y realmente escalable, pero nunca llega a tocar un stack de cliente real, así que para una aplicación en tiempo real no puede ejercitar lo que de verdad se está probando.
- Pruebas E2E completamente reales, a pequeña escala. Fidelidad alta, navegadores reales haciendo cosas reales, pero lo bastante caras por instancia como para no escalar por sí solas a miles de usuarios concurrentes, según la propia recomendación de Grafana citada arriba.
- Pruebas de carga híbridas. Un compromiso práctico, unos pocos navegadores reales junto a una multitud grande a nivel de protocolo, pero el lado de protocolo sigue sin poder reportar telemetría real del lado del cliente, porque nunca fue un cliente real para empezar.
- Herramientas de carga específicas para un protocolo (como openvidu-loadtest). Navegadores reales a escala real, construidas específicamente para un protocolo, más cerca de lo que necesita de verdad una aplicación en tiempo real que las otras tres. Pero coordinar un número grande de esas instancias, y recoger información rica del lado del cliente de cada una de ellas, no es algo que estas herramientas extiendan de forma masiva, y cada una suele ser una herramienta hecha a medida para su propio propósito, no pensada para reutilizar la suite E2E que un equipo ya tiene.
Cómo enfocamos las pruebas E2E para medios en tiempo real (y escenarios similares)
Nuestro enfoque se descompone en cuatro piezas.
Definir a los actores. No todos los usuarios simulados necesitan ser idénticos. Un escenario realista a menudo necesita varios roles, presentadores y espectadores en una videollamada, por ejemplo, cada uno con sus propias acciones (unirse, silenciarse, compartir pantalla, cambiar de vista) y sus propias aserciones (qué debería ver, oír o recibir realmente ese rol para que la prueba se considere superada). Muchas de esas acciones y aserciones tampoco necesitan escribirse desde cero: una suite E2E ya existente las codifica para el caso de corrección funcional, y definir un actor alrededor de esa misma suite significa reutilizarla tal cual, no construir un script aparte.
Escalar navegadores o clientes. Una versión "sencilla" de ERTSA, el mismo patrón de cómputo elástico y efímero que hay detrás de la plataforma que se está probando, es lo que hace viable económicamente ejecutar cuantos actores necesite un escenario, instancias de navegador real incluidas, solo durante la duración de la prueba, en lugar de una flota permanente e inactiva.
Coordinar los flujos de usuario. Miles de actores simulados e independientes no actúan de forma coherente por sí solos; algo tiene que secuenciar lo que hace cada uno de ellos, y razonar correctamente sobre cuándo lo hizo realmente cada uno, no solo cuándo llegó un informe sobre ello. Es el mismo problema que el caso de estudio de ERTSA describía para ordenar de forma justa la respuesta de un espectador en directo a un evento dentro del stream, una cola relativa en lugar de una simple, y que reaparece aquí por una razón distinta: no la justicia hacia una audiencia en directo, sino la corrección del propio resultado de la prueba.
Recoger eventos, información y evidencias. Una parte importante de lo que de verdad importa,
bitrate, jitter, pérdida de paquetes, la calidad realmente experimentada, solo existe dentro del
propio cliente de cada actor; el servidor puede confirmar que envió los datos, no cómo llegaron
en realidad. Cada actor reporta sus propios datos del lado del cliente (el mismo tipo de datos
que expone la API getStats() de un navegador real) de vuelta a ese mismo flujo coordinado, y
donde la calidad es genuinamente subjetiva, grabar vídeo de la navegación simulada le da a quien
revisa una evidencia real que juzgar, no solo un número que dar por bueno.
El objetivo decide los detalles
Ninguna de esas cuatro piezas tiene una única forma fija; lo que una prueba intenta demostrar de verdad es lo que decide todo lo demás. A veces el objetivo es encontrar el punto de ruptura, hasta dónde puede llegar esto antes de fallar. Otras veces es garantizar que un parámetro se mantiene dentro de unos límites, QoE, rendimiento del servidor, condiciones de red concretas, en lugar de buscar un límite. En nuestra experiencia, ese objetivo es lo que de verdad condiciona todo lo demás: cómo tienen que ser los actores, qué hay que comprobar en el lado del cliente, qué se mide en el lado del sistema, cómo aumenta la carga a lo largo de la prueba y cuánto tiempo necesita durar. Afinar esos detalles según la pregunta real que se está haciendo es la mayor parte del trabajo de verdad.
Esto no es una plataforma, es un enfoque
Nada de lo descrito aquí se distribuye como una única herramienta cerrada. Es un patrón de arquitectura, construido con piezas, frameworks E2E ya existentes, el cómputo elástico de ERTSA y la capa de coordinación y recogida de información descrita arriba, adaptado a cualquier sistema en tiempo real y a la suite de pruebas que un equipo ya tenga. ¿Se beneficiaría tu aplicación de este enfoque? Hablemos.