mitmproxy in UI-Autotests integrieren: Traffic-Steuerung für QA-Engineers
Das Proxying von Netzwerkverkehr ist ein Gamechanger, um die Effizienz von UI-Autotests zu steigern. Im Gegensatz zum manuellen Testen mit Tools wie Charles Proxy oder Fiddler erfordert Automatisierung programmierbare Lösungen. Mitmproxy mit seiner Python-API und dem headless Modus lässt euch eine steuerbare Netzwerkschicht direkt in eure Testinfrastruktur einbinden.
Warum Proxies in der automatisierten Testung entscheidend sind
UI-Autotests leiden oft unter „Netzwerkblindheit“ – sie erkennen Probleme mit APIs, WebSockets oder Backend-Services nicht. Das führt zu instabilen Tests, falschen Fehlern und schwierigem Debugging. Ein Proxy sorgt für volle Netzwerktransparenz. Wichtige Anwendungsfälle:
- Abfangen und Analysieren von HTTP-Anfragen/Antworten zur Überprüfung des App-Verhaltens.
- Anpassen von Statuscodes (z. B. 200 → 404), um clientseitige Fehlerbehandlung zu testen.
- Ersetzen von Daten in JSON/XML-Antworten, um Testszenarien ohne Dev-Umgebungen zu simulieren.
- Protokollieren von Traffic und Nachverfolgen von Anfrage-Sequenzen.
- Behandeln von WebSocket-Nachrichten, inklusive Live-Injection und -Änderung.
Warum mitmproxy die Top-Wahl ist
Tools wie Charles, Proxyman und Fiddler eignen sich nicht für Automatisierung, da ihnen externe Steuerungs-APIs fehlen. Das Open-Source-Tool mitmproxy überzeugt durch:
- Python-API zum Skripten von Traffic-Abfang und -Änderung.
- Headless-Modus für CI/CD-Pipelines ohne GUI.
- WebSocket-Unterstützung, essenziell für moderne Web- und Mobile-Apps.
- Plattformübergreifend (Windows, Linux, macOS).
Mitmproxy läuft in drei Modi: mitmproxy (interaktive CLI), mitmweb (Web-UI) und mitmdump (nicht-interaktiver Dump). Für Autotests nutzt mitmdump oder mitmweb mit Custom-Skripten.
Integrationsarchitektur mit Test-Frameworks
Startet mitmproxy als eigenständigen Prozess, unabhängig vom Test-Framework. Die Kommunikation läuft über eine Konfigurationsdatei (z. B. config.json) und ein Python-Modul (proxy_handler.py). Ablauf:
- Mitmproxy installieren (z. B.
brew install mitmproxy). - Zertifikate auf Testgeräten für HTTPS-Abfang einrichten.
- Starten mit
mitmweb -s proxy_handler.py. - Proxy-Verhalten dynamisch per Update von config.json aus Tests steuern.
Statuscode-Mocking: Praktisches Beispiel
Mocken wir HTTP-Statuscodes für spezifische APIs. In config.json definieren:
{
"status": {"api/v1/user": 404, "api/v2/settings": 500}
}
Einmalige Mocks als Zahl, fortlaufende als Liste (z. B. [404]). Das Modul proxy_handler.py übernimmt:
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
Wichtige Umsetzungshinweise:
- Regex (re-Modul) für flexible URI-Abstimmung.
- Unterstützung für einmalige und persistente Mocks.
- Logging für einfaches Debugging.
- Dateioperationen in separater FileWorker-Klasse für sauberen Code.
Erweiterte Funktionen: Daten-Mocking und Logging
Ähnlich Response-Bodies mocken. „mock“-Abschnitt in config.json ergänzen:
{
"mock": {"api/v1/data": {"field": "new_value"}}
}
In 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
Zum Speichern von Server-Antworten in Dateien (ideal für Analysen) „get_response“-Abschnitt in config.json nutzen. Perfekt für:
- Validierung von Datenstrukturen in automatisierten Checks.
- Aufbau von Golden Responses für Regressionstests.
- Debugging kniffliger Backend-Interaktionen.
Wichtige Erkenntnisse
- Netzwerktransparenz: Proxies beheben die Blindstellen von Autotests bei Netzwerkproblemen und steigern Diagnose und Zuverlässigkeit.
- Mitmproxy-Flexibilität: Python-API und WebSocket-Support ermöglichen komplexe Traffic-Szenarien ohne GUI-Abhängigkeiten.
- Konfigurationsgesteuerte Steuerung: JSON-Konfigs machen dynamische Proxy-Anpassungen nahtlos für Test-Frameworks.
- Performance: Handler optimieren, um Verlangsamungen von Proxy oder Tests zu vermeiden.
- Erweiterbarkeit: Modulares Design (proxy_handler.py, FileWorker) erleichtert Ergänzungen wie Throttling oder WebSocket-Analyse.
Fazit
Die Integration von mitmproxy in UI-Autotests verwandelt Proxies von manuellen Tools in automatisierte Powerhouses. Sie boostet clientseitiges Testen, besonders bei Backend-Simulationen und tiefer Netzwerküberwachung. Balanciert Konfigurationsflexibilität mit Handler-Performance für Erfolg.
— Editorial Team
Noch keine Kommentare.