Powrót do strony głównej

Mitmproxy w UI-autotestach: zarządzanie ruchem dla QA

Artykuł wyjaśnia, jak zintegrować mitmproxy w UI-autotesty do zarządzania ruchem sieciowym. Omówiono praktyczne przykłady w Pythonie, w tym podstawianie kodów statusu i modyfikację danych, z naciskiem na architekturę i wydajność rozwiązania.

Automatyzacja testowania: jak używać mitmproxy w UI-autotestach
Advertisement 728x90

Integracja mitmproxy w testy automatyczne UI: zarządzanie ruchem dla inżynierów QA

Proxyowanie ruchu sieciowego to krytycznie ważne narzędzie do zwiększania efektywności testów automatycznych UI. W przeciwieństwie do testów manualnych, gdzie używa się Charles Proxy lub Fiddler, automatyzacja wymaga programowalnych rozwiązań. Mitmproxy, dzięki Python API i trybowi headless, umożliwia wdrożenie kontrolowanej warstwy sieciowej bezpośrednio w infrastrukturę testową.

Dlaczego proxy jest potrzebne w testach automatycznych

Testy automatyczne UI często cierpią na "ślepotę sieciową" – niezdolność do wykrywania problemów związanych z API, WebSocket czy backendem. Prowadzi to do flaky testów, fałszywych błędów i trudności w diagnozie. Integracja proxy rozwiązuje te problemy, dodając testom widoczność sieciową. Kluczowe zastosowania:

  • Przechwytywanie i analiza żądań HTTP oraz odpowiedzi do weryfikacji zachowania aplikacji.
  • Modyfikacja kodów statusu (np. 200 → 404) do testowania obsługi błędów po stronie klienta.
  • Podmiana danych w odpowiedziach JSON/XML do symulacji stanów testowych bez użycia środowisk DEV.
  • Logowanie ruchu i śledzenie sekwencji żądań.
  • Praca z wiadomościami WebSocket, w tym wstrzykiwanie i modyfikacja w locie.

Wybór mitmproxy jako optymalnego rozwiązania

Charles, Proxyman i Fiddler nie nadają się do automatyzacji z powodu braku API do zewnętrznego zarządzania. Mitmproxy, jako narzędzie open-source, oferuje:

Google AdInline article slot
  • Python API do pisania skryptów przechwytujących i modyfikujących ruch.
  • Tryb headless do uruchamiania w środowiskach CI bez interfejsu graficznego.
  • Obsługę WebSocket, co jest kluczowe dla nowoczesnych aplikacji mobilnych i webowych.
  • Wieloplatformowość (Windows, Linux, macOS).

Mitmproxy działa w trzech trybach: mitmproxy (interaktywne CLI), mitmweb (interfejs webowy) i mitmdump (wyjście nieinteraktywne). Do testów automatycznych używa się mitmdump lub mitmweb z niestandardowymi skryptami.

Architektura integracji z frameworkiem testowym

Uruchomienie mitmproxy odbywa się jako osobny proces, niezależny od frameworka testowego. Interakcja między nimi organizowana jest przez plik konfiguracyjny (np. config.json) i moduł Python (proxy_handler.py). Podstawowy przepływ:

  • Instalacja mitmproxy (np. przez brew install mitmproxy).
  • Konfiguracja certyfikatów na urządzeniach testowych do przechwytywania ruchu HTTPS.
  • Uruchomienie proxy komendą mitmweb -s proxy_handler.py.
  • Dynamiczne zarządzanie zachowaniem proxy przez aktualizację config.json z testów.

Implementacja podmiany kodów statusu: praktyczny przykład

Rozważmy przypadek modyfikacji statusów HTTP dla konkretnych API. Konfiguracja ustawiana jest w config.json:

Google AdInline article slot
{
    "status": {"api/v1/user": 404, "api/v2/settings": 500}
}

Do jednorazowej podmiany używa się wartości-numer, do długotrwałej – listy (np. [404]). Moduł proxy_handler.py obsługuje te ustawienia:

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

Kluczowe punkty implementacji:

  • Użycie wyrażeń regularnych (moduł re) do elastycznego dopasowania URI.
  • Obsługa obu formatów konfiguracji (jednorazowa i długotrwała podmiana).
  • Logowanie operacji do debugowania.
  • Wydzielenie pracy z plikami do osobnej klasy (FileWorker) dla czystości kodu.

Rozszerzenie funkcjonalności: mockowanie danych i logowanie

Analogicznie do podmiany statusów, można zaimplementować modyfikację treści odpowiedzi. W config.json dodaje się sekcję "mock":

Google AdInline article slot
{
    "mock": {"api/v1/data": {"field": "new_value"}}
}

W proxy_handler.py obsługa wygląda tak:

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

Do zapisywania odpowiedzi serwera do plików (np. do późniejszej analizy) używa się sekcji "get_response" w config.json. To jest przydatne dla:

  • Weryfikacji struktury danych w automatycznych sprawdzeniach.
  • Tworzenia wzorcowych odpowiedzi do testów regresyjnych.
  • Debugowania skomplikowanych scenariuszy interakcji z backendem.

Co jest ważne

  • Network visibility: Integracja proxy eliminuje "ślepotę" testów automatycznych do problemów sieciowych, poprawiając diagnozę i stabilność.
  • Elastyczność mitmproxy: Python API i obsługa WebSocket umożliwiają tworzenie złożonych scenariuszy modyfikacji ruchu bez zależności od narzędzi GUI.
  • Zarządzanie konfiguracyjne: Użycie config.json do dynamicznej zmiany zachowania proxy upraszcza integrację z frameworkami testowymi.
  • Wydajność: Kod handlerów musi być zoptymalizowany, aby nie spowalniać działania proxy i testów.
  • Rozszerzalność: Architektura oparta na modułach (proxy_handler.py, FileWorker) pozwala łatwo dodawać nową funkcjonalność, np. throttling czy analizę WebSocket.

Podsumowanie

Wdrożenie mitmproxy w testy automatyczne UI przekształca proxy z narzędzia manualnej analizy w kontrolowany komponent zautomatyzowanej weryfikacji. Znacząco rozszerza to możliwości testowania aplikacji klienckich, zwłaszcza w scenariuszach wymagających symulacji specyficznych stanów backendu lub szczegółowego monitorowania interakcji sieciowych. Dla udanej integracji kluczowe jest zachowanie równowagi między elastycznością konfiguracji a wydajnością handlerów ruchu.

— Editorial Team

Advertisement 728x90

Czytaj dalej