Automatisierter QA / Stability Test

Dieses Projekt zeigt einen automatisierten Testansatz zur Überprüfung der Stabilität, Verfügbarkeit und Performance eines HTTP-Services ( API oder Microservice).

Python HTTP Smoke Test Stability Availability Latenz (p50/p95) Logging JSON Report requests

1. Projektziel

Ziel ist ein einfacher, reproduzierbarer und automatisierter Test für HTTP-basierte Services.

2. Motivation – Warum dieses Projekt?

Problem

Typische Herausforderungen

  • Manuelle Tests sind zeitaufwendig und wiederholen sich
  • Fehler sind schwer reproduzierbar (“Works on my machine”)
  • Bei einem FAIL fehlt oft Kontext (Logs, Zeitpunkt, Status)
Lösung

Was das Skript liefert

  • Automatisierte Testausführung mit klaren Kriterien
  • Einheitliche Logs (Konsole + Datei)
  • JSON-Report: Kennzahlen + alle Einzelmessungen

3. Architekturübersicht

Das Skript startet den Service nicht selbst. Es übernimmt die Rolle eines Test-Clients, der beobachtet, misst und dokumentiert. Der Service kann lokal laufen.

4. Ablauf – Was passiert wirklich?

Schritt 1

Start & Parameter

Das Skript wird über CLI gestartet. Parameter definieren “Was”, “Wie lange” und “Wie streng” getestet wird.

Schritt 2

Logging Initialisierung

Es wird in die Konsole und in eine Datei geloggt. So sind Testläufe später nachvollziehbar.

Schritt 3

Stability Test Loop

  1. HTTP GET senden (probe)
  2. Latenz messen (ms)
  3. Status prüfen (2xx = OK)
  4. Optional: Expected-Text im Body prüfen
  5. Ergebnis speichern + OK/FAIL loggen
  6. Warten (Interval) → nächster Durchlauf
Schritt 4

Auswertung + Report

Am Ende werden Kennzahlen berechnet (Availability, p50/p95 etc.) und ein JSON-Report erzeugt.

Schritt 5

Docker Logs

Wenn der Service in Docker läuft und ein Containername angegeben wird, werden die letzten Logzeilen gesammelt und in den Report eingebettet.

5. Implementierung – Wichtige technische Entscheidungen

Technologie-Stack

  • Python – Lesbarkeit & schnelle Anpassung
  • requests – stabile HTTP Requests
  • logging – standardisierte Logs
  • dataclasses – klare Struktur pro Ergebnis
  • JSON – teamfähiges Reporting

Qualitätsprinzipien

  • Reproduzierbar: gleiche Parameter → gleicher Test
  • Robust: Fehler werden erfasst, nicht “verschluckt”
  • Teamfähig: Logs + Report als Evidenz
  • Erweiterbar: Basis für CI-Integration

6. Resultate – Success & Failure Cases

✅ Erfolgsfall

Beispiel: gültiger Endpoint /health liefert 200 + Body enthält OK.

  • Status: 200
  • Availability: 100%
  • p50/p95: messbar (z.B. ~15–20ms lokal)
  • Report: summary + results vorhanden
Interpretation: Service ist erreichbar, stabil und erfüllt die definierten Kriterien.

❌ Fehlerfall

Beispiel: ungültiger Endpoint /wrong liefert 404.

  • Status: 404
  • Availability: 0%
  • p50/p95: None (weil keine OK-Requests)
  • Fehlertext: z.B. Expected 'OK' not found
Interpretation: Fehler ist reproduzierbar, sauber dokumentiert und direkt an das Team kommunizierbar.

Beispiel-Ausführung

pip install requests
# Erfolgsfall
python qa_test.py --url http://127.0.0.1:8000/health --duration 10 --interval 1 --timeout 2 --expected "OK"


Nexus Repository – Uploaded Artifact
Nexus Repository – Uploaded Artifact

# Fehlerfall
python qa_test.py --url http://127.0.0.1:8000/wrong --duration 6 --interval 1 --timeout 2 --expected "OK"


Nexus Repository – Uploaded Artifact
Nexus Repository – Uploaded Artifact

Unterschied zwischen localhost und 127.0.0.1 – Einfluss auf die Latenz

Während der Tests ist aufgefallen, dass sich die gemessene Latenz deutlich unterscheidet, je nachdem ob der Service über localhost oder 127.0.0.1 angesprochen wird.

localhost

  • localhost ist ein Hostname, kein direktes Netzwerkziel
  • Der Name wird zuerst über die Namensauflösung aufgelöst (/etc/hosts oder DNS)
  • Auf vielen Systemen wird localhost zuerst auf ::1 (IPv6) gemappt
  • Dadurch kann zusätzlicher Overhead entstehen (IPv6 → IPv4 Fallback)

127.0.0.1

  • 127.0.0.1 ist eine direkte IPv4 Loopback-Adresse
  • Keine Namensauflösung notwendig
  • Der Netzwerk-Stack wird direkter angesprochen
  • In der Regel geringere und stabilere Latenz

Auswirkung auf die gemessene Latenz

Test mit localhost
Höhere und schwankendere Latenzen (~2000 ms in den Tests), da zusätzliche Schritte in der Namensauflösung und im Netzwerk-Stack durchlaufen werden.
Nexus Repository – Uploaded Artifact
Test mit 127.0.0.1
Deutlich geringere und stabilere Latenzen (~10–20 ms), da der Service direkt über die Loopback-Adresse angesprochen wird.
Nexus Repository – Uploaded Artifact

Fazit:
Für präzise Latenz- und Stabilitätstests sollte bevorzugt 127.0.0.1 verwendet werden, da es den Netzwerk-Overhead minimiert und realistischere Aussagen über die tatsächliche Performance des Services erlaubt.

7. Mögliche Verbesserungen

Technische Erweiterungen

  • Bessere Fehlerklassifikation (Netzwerk vs. Applikation)
  • Unterstützung für HTTPS/Zertifikate (falls benötigt)

QA / Reporting

  • CSV Export zusätzlich zu JSON
  • Nur bei FAIL automatisch Docker-Logs anhängen

8. Verbesserung – Fehlerklassifikation (Netzwerk vs. Applikation)

In der Praxis ist ein „FAIL“ allein oft nicht genug. Entscheidend ist, warum es fehlschlägt: Ist es ein Netzwerk-/Infrastrukturproblem (Timeout, DNS, Connection refused) oder ein Applikationsproblem (404/500) bzw. ein Validierungsproblem (200 OK, aber falscher Inhalt)?

Ziel

Schnellere Root-Cause Analyse

  • Network: DNS/Timeout/Connection Error → eher Infra/Netzwerk
  • Application: 4xx/5xx → eher Endpoint/Backend/Config
  • Validation: 2xx aber Expected-Text fehlt → Contract/Business-Logik
Umsetzung

Erweiterung des Result-Objekts

Pro Request wird zusätzlich ein Feld error_context gespeichert (z.B. network, application, validation).

# Beispiel (Konzept)
Result(
    timestamp=..., 
    latency_ms=..., 
    status_code=..., 
    ...,
    error_context: Optional[str] = None 
)
# Fehlerfall(Fehlerklassifikation)
python qa_test.py --url http://127.0.0.1:8000/wrong --duration 6 --interval 1 --timeout 2 --expected "OK"


Nexus Repository – Uploaded Artifact
Warum das wichtig ist: Ohne Klassifikation sieht man nur „FAIL“. Mit Klassifikation kann man sofort unterscheiden, ob man z.B. Firewall/DNS prüfen muss (network) oder den Endpoint/Backend (application).