Automatisierte Tests (IT)QA Automation Engineer

Wie implementiert man korrekt die Verarbeitung von Wartezeiten und Synchronisation in automatisierten UI-Tests?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

Zu Beginn der Automatisierung von UI-Tests bestand die Hauptschwierigkeit in der Instabilität der Tests aufgrund von Verzögerungen beim Erscheinen von Elementen sowie der Notwendigkeit, auf asynchrone Aktionen auf der Seite zu warten. Früher verwendeten Tester oft feste Pausen (sleep), was zu langen Testlaufzeiten und geringer Stabilität führte.

Das Problem liegt darin, dass Webanwendungen immer dynamischer werden. Elemente erscheinen und verschwinden asynchron, und die gleichzeitige Arbeit von Frontend und Backend kann Situationen hervorrufen, in denen Tests wegen falscher Erwartungen bezüglich des UI-Zustands fehlschlagen. Statische Pausen wie Thread.sleep(1000) erhöhen lediglich die Testzeit und garantieren keinen erfolgreichem Testverlauf.

Die Lösung besteht darin, explizite und implizite Wartezeiten (explicit/implicit waits) zu verwenden, die eine flexiblere und effektivere Synchronisation der Aktionen mit dem tatsächlichen Zustand der Benutzeroberfläche ermöglichen. Beispielsweise werden in Selenium oder ähnlichen Frameworks WebDriverWait oder deren Entsprechungen verwendet, um das Erscheinen der benötigten Elemente unter bestimmten Bedingungen zu überprüfen:

from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) element = wait.until(EC.presence_of_element_located((By.ID, "myElem")))

Wichtige Merkmale:

  • Geringere Ausfallzeiten der Tests: Die Tests fahren fort, sobald die Bedingung eintritt.
  • Reduzierung des Anteils an flüchtigen Tests (flaky tests) aufgrund der Dynamik des UI.
  • Höherer Abstraktionsgrad (Warten auf komplexe Bedingungen, z. B. auf die Änderung eines Textwerts oder das Verschwinden von Elementen).

Trickfragen.

Warum sollte man nicht nur implizite Wartezeiten (implicit waits) anstelle von expliziten verwenden?

Implizite Wartezeiten gelten für den gesamten Treiber und können zu unerwarteten Verzögerungen oder Konflikten mit expliziten Wartezeiten führen, was häufig zu Fehlern „TimeoutException“ führt.

Sollte man Thread.sleep für Wartezeiten in UI-Tests verwenden?

Die Verwendung von Thread.sleep wird dringend abgeraten: Es führt zu unnötigen Verzögerungen und Instabilität der Tests. Besser sind explizite Wartezeiten und Bedingungen zu verwenden.

Was tun, wenn ein Element mit Animation erscheint?

Auf das Erscheinen nicht nur des Elements selbst, sondern auch seines Zustands (z. B. Sichtbarkeit oder Klickbarkeit) warten, indem man spezielle Bedingungen wie visibility_of_element_located verwendet.

Typische Fehler und Anti-Patterns

  • Verwendung fester Timeouts (sleep) anstelle von Bedingungen.
  • Konflikt zwischen expliziten und impliziten Wartezeiten.
  • Warten auf die Existenz eines Elements, wo man besser auf die Sichtbarkeit oder Bereitschaft zur Interaktion warten sollte.

Beispiel aus der Praxis

Negativer Fall

Im Projekt wurde das Warten auf das Auftauchen eines Modalfensters mit Thread.sleep(3000) realisiert. Manchmal erschien das Fenster schneller, manchmal langsamer. Die Skripte arbeiteten langsam, und bei erhöhter Last fielen die Tests gelegentlich aus.

Vorteile:

  • Einfachheit der Implementierung.
  • Schnelle Umsetzung ohne sich mit Synchronisation zu befassen.

Nachteile:

  • Instabilität der Tests.
  • Erhöhte Dauer der automatisierten Tests in allen Umgebungen.
  • Schwierigkeit bei der Wartung bei Änderungen der UI.

Positiver Fall

Die Logik wurde überarbeitet – alle Aktionen mit der UI wurden in Funktionen mit expliziten Wartezeiten auf Sichtbarkeit und Aktivität der Elemente gekapselt, alles wurde schneller, die Stabilität stieg auf 98%.

Vorteile:

  • Stabile und schnelle Tests.
  • Einfache Skalierbarkeit und Wartung von Szenarien.

Nachteile:

  • In der Implementierungsphase war Zeit erforderlich, um alle Nuancen der Synchronisation herauszufinden.