Integrar mitmproxy en autotests de UI: Control de tráfico para QA
Interceptar el tráfico de red es un cambio radical para mejorar la eficiencia de los autotests de UI. A diferencia del testing manual con herramientas como Charles Proxy o Fiddler, la automatización requiere soluciones programables. Mitmproxy, con su API de Python y modo sin interfaz gráfica, te permite integrar una capa de red controlable directamente en tu infraestructura de pruebas.
Por qué los proxies son clave en testing automatizado
Los autotests de UI suelen padecer de "ceguera de red": no detectan problemas en APIs, WebSockets o servicios backend. Esto genera pruebas inestables, fallos falsos y depuración complicada. Añadir un proxy otorga visibilidad total de la red. Casos de uso principales:
- Interceptar y analizar peticiones/respuestas HTTP para verificar el comportamiento de la app.
- Modificar códigos de estado (ej. 200 → 404) para probar el manejo de errores en el cliente.
- Sustituir datos en respuestas JSON/XML para simular escenarios sin entornos de desarrollo.
- Registrar tráfico y rastrear secuencias de peticiones.
- Manejar mensajes WebSocket, con inyección y modificación en tiempo real.
Por qué mitmproxy es la mejor opción
Herramientas como Charles, Proxyman o Fiddler fallan en automatización por falta de APIs de control externo. El open-source mitmproxy destaca con:
- API de Python para scripting de intercepción y modificación de tráfico.
- Modo sin GUI ideal para pipelines CI/CD.
- Soporte para WebSocket, esencial en apps web y móviles modernas.
- Multiplataforma (Windows, Linux, macOS).
Mitmproxy funciona en tres modos: mitmproxy (CLI interactivo), mitmweb (interfaz web) y mitmdump (dump no interactivo). Para autotests, usa mitmdump o mitmweb con scripts personalizados.
Arquitectura de integración con frameworks de pruebas
Ejecuta mitmproxy como proceso independiente del framework de tests. Se comunican vía archivo de config (ej. config.json) y un módulo Python (proxy_handler.py). Flujo básico:
- Instala mitmproxy (ej.
brew install mitmproxy). - Configura certificados en dispositivos de prueba para interceptar HTTPS.
- Lanza con
mitmweb -s proxy_handler.py. - Controla dinámicamente el proxy actualizando config.json desde los tests.
Mocking de códigos de estado: Ejemplo práctico
Simulemos códigos de estado HTTP para APIs específicas. Defina en config.json:
{
"status": {"api/v1/user": 404, "api/v2/settings": 500}
}
Usa un número para mocks únicos, o una lista (ej. [404]) para persistentes. El módulo proxy_handler.py lo gestiona:
import re
import mitmproxy.ctx as ctx
from mitmproxy import http
from file_worker import FileWorker
file_worker = FileWorker()
def response(flow: http.HTTPFlow) -> None:
url = flow.request.url
if not flow.response.content:
return
cfg = file_worker.get_proxy_params()
cfg_status = cfg.get("status")
for api, sc in list(cfg_status.items()):
if bool(re.compile(api).search(url)):
flow.response.status_code = int(sc[0] if isinstance(sc, list) else sc)
ctx.log.info(f"Status code was mocked '{api}' -> {sc}")
if not isinstance(sc, list):
del cfg_status[api]
file_worker.set_proxy_param("status", cfg_status)
cfg["status"] = cfg_status
break
Notas clave de implementación:
- Regex (módulo re) para coincidencias flexibles de URI.
- Soporte para mocks únicos y persistentes.
- Logging para depuración sencilla.
- Operaciones de archivo en clase FileWorker para código limpio.
Ampliando capacidades: Mocking de datos y logging
De forma similar, simula cuerpos de respuesta. Añade sección "mock" en config.json:
{
"mock": {"api/v1/data": {"field": "new_value"}}
}
En proxy_handler.py:
cfg_mock: dict = cfg.get("mock")
if cfg_mock:
for mock_api, params in list(cfg_mock.items()):
if bool(re.compile(mock_api).search(url)):
data = flow.response.content.decode()
modified = file_worker.mock(params[0] if isinstance(params, list) else params, data)
if modified:
flow.response.content = modified.encode()
ctx.log.info(f"Param {params} were mocked for '{mock_api}'")
if not isinstance(params, list):
del cfg_mock[mock_api]
file_worker.set_proxy_param("mock", cfg_mock)
cfg["mock"] = cfg_mock
break
Para guardar respuestas del servidor en archivos (ideal para análisis), usa sección "get_response" en config.json. Perfecto para:
- Validar estructuras de datos en checks automatizados.
- Crear respuestas "doradas" para tests de regresión.
- Depurar interacciones backend complejas.
Lecciones clave
- Visibilidad de red: Los proxies eliminan puntos ciegos de los autotests en problemas de red, mejorando diagnósticos y fiabilidad.
- Flexibilidad de mitmproxy: API de Python y soporte WebSocket permiten escenarios complejos sin depender de GUI.
- Control por config: JSON hace ajustes dinámicos del proxy sin fisuras para frameworks de tests.
- Rendimiento: Optimiza handlers para no ralentizar proxy ni tests.
- Extensibilidad: Diseño modular (proxy_handler.py, FileWorker) facilita añadir features como throttling o análisis WebSocket.
Conclusión
Integrar mitmproxy en autotests de UI convierte proxies de herramientas manuales en potencias automatizadas. Potencia el testing del lado cliente, especialmente simulaciones backend y monitoreo profundo de red. Equilibra flexibilidad de config con rendimiento de handlers para triunfar.
— Editorial Team
Aún no hay comentarios.