Automated Testing (IT)QA Automation Engineer

Hoe implementeer je correct het afhandelen van wachttijden en synchronisatie in geautomatiseerde UI-tests?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

In het begin van de automatisering van UI-testen was de grootste uitdaging de onbetrouwbaarheid van tests door vertragingen bij het verschijnen van elementen, evenals de noodzaak om te wachten op asynchrone acties op de pagina. Testers gebruikten vaak harde vertragingen (sleep), wat leidde tot lange testuitvoeringen en een lage stabiliteit.

Het probleem is dat webapplicaties steeds dynamischer worden. Elementen verschijnen en verdwijnen asynchroon, en de gelijktijdige werking van de frontend en backend kan situaties veroorzaken waarin tests faalden vanwege onjuiste verwachtingen van de UI-status. Statische pauzes, zoals Thread.sleep(1000), verhogen alleen de testtijd en garanderen niet dat de test succesvol is.

De oplossing is het gebruik van expliciete en impliciete wachttijden (explicit/implicit waits), die het mogelijk maken om acties flexibeler en effectiever te synchroniseren met de werkelijke staat van de interface. Bijvoorbeeld, in Selenium of soortgelijke frameworks worden WebDriverWait of vergelijkbare methoden gebruikt om het verschijnen van de benodigde elementen te controleren aan de hand van een voorwaarde:

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")))

Belangrijke kenmerken:

  • Minder stilstandtijd van tests: tests gaan verder zodra de voorwaarde is vervuld.
  • Vermindering van het percentage valse positieven (flaky tests) door de dynamiek van de UI.
  • Een hoger abstractieniveau (verwachtingen op complexe voorwaarden, bijvoorbeeld op het veranderen van tekstwaarde of het verdwijnen van elementen).

Misleidende vragen.

Waarom is het beter om niet alleen impliciete wachttijden (implicit waits) te gebruiken in plaats van expliciete?

Impliciete wachttijden worden toegepast op de hele driver en kunnen leiden tot onverwachte vertragingen of conflicten met expliciete wachttijden, wat vaak resulteert in 'TimeoutException' fouten.

Moet je Thread.sleep gebruiken voor wachttijden in UI-tests?

Het gebruik van Thread.sleep wordt ten zeerste afgeraden: dit leidt tot onnodige vertragingen en onbetrouwbaarheid van tests. Het is beter om expliciete wachttijden en voorwaarden te gebruiken.

Wat te doen als een element verschijnt met animatie?

Wacht niet alleen op het verschijnen van het element, maar ook op zijn status (bijvoorbeeld zichtbaarheid of klikbaarheid), door speciale voorwaarden zoals visibility_of_element_located te gebruiken.

Typische fouten en anti-patronen

  • Het toepassen van vaste time-outs (sleep) in plaats van voorwaarden.
  • Conflict tussen expliciete en impliciete wachttijden.
  • Wachten op het bestaan van een element, terwijl je eigenlijk moet wachten op zijn zichtbaarheid of gereedheid voor interactie.

Voorbeeld uit de praktijk

Negatieve case

In het project werd de wachttijd voor het verschijnen van het modale venster gerealiseerd via Thread.sleep(3000). Soms verscheen het venster sneller, soms langzamer. De scripts werkten traag en bij hogere belasting faalden de tests soms.

Voordelen:

  • Eenvoudige implementatie.
  • Snel gerealiseerd zonder in detail in synchronisatie te duiken.

Nadelen:

  • Onbetrouwbaarheid van tests.
  • Verhoogde tijd voor het doorlopen van geautomatiseerde tests op alle omgevingen.
  • Moeilijk te onderhouden bij wijzigingen in de UI.

Positieve case

De logica werd herzien — alle acties met de UI werden gewikkeld in functies met expliciete wachttijden voor zichtbaarheid en activiteit van elementen, alles werd sneller en de stabiliteit steeg tot 98%.

Voordelen:

  • Stabiele en snelle tests.
  • Gemakkelijke schaalbaarheid en onderhoud van scenario's.

Nadelen:

  • Tijdens de implementatiefase was er tijd nodig om alle nuances van synchronisatie te achterhalen.