Introductie
Flaky tests zijn de doodsteek van het bestaan van elke automatiseringsingenieur. Een van de belangrijkste boosdoeners van slordige tests zijn onjuiste of onvoldoende wachtmechanismen. In dit artikel gaan we dieper in op de wachtstrategieën van WebDriverIO en Java Selenium.
Java Selenium wacht
Java’s Selenium WebDriver biedt twee primaire typen wachttijden: impliciet en expliciet.
1. Impliciet wachten
Wat het doet: wacht automatisch een bepaalde tijd voordat een NoSuchElementException wordt gegenereerd als de WebDriver het element niet op de pagina kan vinden. Het is ingesteld voor de volledige duur van de WebDriver-instantie en is van toepassing op alle elementen.
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// waits for a target selector to be displayed
Voordelen:
Eenvoudig in te stellen. Globaal van toepassing op alle findElement () en findElements () aanroepen.
Nadelen:
Niet aanbevolen voor moderne webtoepassingen met dynamische inhoud, omdat het een statische wachttijd is. Kan tests vertragen als de ingestelde duur langer is dan nodig.
Wanneer te gebruiken: Om een basislijn in te stellen, moet u de hele testsessie afwachten.
2. Expliciet wachten
Wat het doet: Wacht tot aan een specifieke voorwaarde is voldaan (bijvoorbeeld een element dat klikbaar of zichtbaar moet zijn, enz.) voordat u verder gaat. Gebruikt de WebDriverWait-klasse in combinatie met de ExpectedConditions-klasse.
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("elementId")));
Voordelen:
Dynamischer dan Implicit Wait. Maakt specifieke omstandigheden mogelijk, waardoor het flexibeler wordt.
Nadelen:
Vereist meer code dan Implicit Wait. Specifiek voor de aandoening en niet wereldwijd van toepassing.
Wanneer te gebruiken: wanneer u moet wachten tot een specifieke voorwaarde, zoals een element, zichtbaar, klikbaar of aanwezig is.
3. Vloeiend wachten
Wat het doet: Met Fluent Wait, vaak aangeduid als „Smart Wait”, kunt u bepalen hoeveel tijd u maximaal moet wachten op een specifieke aandoening en de frequentie waarmee u de toestand moet controleren voordat u een uitzondering genereert. Het kan specifieke soorten uitzonderingen negeren tijdens het wachten, zoals NoSuchElementException bij het zoeken naar een element.
Het lijkt op Explicit Wait, maar biedt meer flexibiliteit. Hiermee kunt u de polling-frequentie opgeven (hoe vaak de conditie moet worden gecontroleerd) en welke uitzonderingen u tijdens de wachttijd moet negeren.
Gebruik:
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
WebElement element = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("elementId"));
}
});
Voordelen:
Zeer aanpasbaar. Kan de peilingsfrequentie definiëren en specifieke uitzonderingen negeren.
Nadelen:
Vereist meer code dan zowel Implicit als Explicit Waits. Misschien overdreven voor eenvoudige scenario’s.
WebDriverIO wacht
1. browser.pause ()
Wat het doet: Introduceert een hardgecodeerde, vaste vertraging.
browser.pause(5000); // Pauses for 5 seconds
Wanneer te gebruiken: Om een basislijn in te stellen, moet u de hele testsessie afwachten.
2. Expliciet wachten
Wat het doet: wacht tot een element zichtbaar is.
const elem = $('selector');
elem.waitForDisplayed(5000);
// waits for a target selector to be displayed
Wanneer te gebruiken: wanneer u een element zichtbaar wilt hebben voordat u ermee kunt interageren.
3. Vloeiend wachten
Als u in WebDriverIO methoden zoals waitForDisplayed (), waitForExist () of waitForClickable () gebruikt, gebruikt u in wezen een vloeiend wachtmechanisme. Deze methoden zullen herhaaldelijk op een voorwaarde controleren totdat aan de voorwaarde is voldaan of een time-out is bereikt, wat het kernidee is achter Fluent Wait.
bijvoorbeeld
const elem = $('selector');
elem.waitForDisplayed({ timeout: 5000, interval: 500 });
In dit voorbeeld:
time-out: 5000 geeft aan dat de methode maximaal 5 seconden moet wachten voordat het element wordt weergegeven. interval: 500 (indien aanwezig) zou aangeven dat de methode de conditie elke 500 milliseconden moet controleren. Dit is vergelijkbaar met hoe Fluent Wait werkt in Java’s Selenium, waar je een time-out en een polling-interval specificeert.
Bovendien biedt de WaitUntil () -methode van WebDriverIO nog meer flexibiliteit, waardoor u aangepaste wachtvoorwaarden kunt definiëren, vergelijkbaar met de flexibiliteit die Fluent Wait biedt in Java:
browser.waitUntil(
() => $('selector').getText() === 'Expected Text',
{
timeout: 5000,
timeoutMsg: 'Expected text to be different after 5s'
}
);
Dus hoewel WebDriverIO zijn wachtmechanismen niet als „Fluent Wait” bestempelt, zijn de functionaliteit en flexibiliteit zeer aanwezig en sluiten ze aan bij het concept van vloeiend wachten. Nu je dit allemaal hebt geleerd en niet in slaap bent gevallen 😃 😃 😃 van dit blog, waar komt het praktische gedeelte om de hoek kijken.
Veelvoorkomende wait-gerelateerde fouten bij bijvoorbeeld Dockerized UI Testing
Bij het uitvoeren van UI-tests in Docker-containers kunnen zich verschillende uitdagingen voordoen, met name met betrekking tot wachttijden. Hier zijn enkele vaak voorkomende fouten en hun mogelijke oplossingen:
1. Time-outfouten
- Foutmeldingen:
- TimeoutUitzondering of
- De wachttijd is verstreken na [x] milliseconden.
- Beschrijving:
- Doet zich voor wanneer niet binnen de opgegeven time-outperiode aan een wachtvoorwaarde is voldaan, vaak omdat de toepassing zich anders of langzamer gedraagt in een container.
2. Element niet gevonden
- Foutmeldingen:
- Geen uitzondering op zo’n element.
- Beschrijving:
- Elementen zijn mogelijk niet aanwezig in de DOM vanwege de langzamere laadtijden in containers, zelfs als er wachttijden zijn ingesteld.
3. Element niet interactief
- Foutmeldingen:
- ElementNotInteractableException.
- Beschrijving:
- Doet zich voor wanneer u probeert te interageren met een element voordat het gereed is, zoals een knop voordat het volledig is gerenderd. Met uitzondering van NoSuchElement is dit het meest voorkomende antwoord dat ik aan studenten moet uitleggen 😃
4. Referentie van Stale Element
- Foutmeldingen:
- StaleElementReferenceException.
- Beschrijving:
- Doet zich voor wanneer de DOM verandert nadat een verwijzing naar een element is verkregen, maar voordat er interactie mee is begonnen.
5. Netwerkfouten
- Foutmeldingen:
- Time-outs van het netwerk, resets van de verbinding.
- Beschrijving:
- Komt vaker voor in gecontaineriseerde omgevingen vanwege netwerkconfiguraties of -beperkingen.
Oplossingen en beste praktijken:
- Wachttijden verhogen: pas de standaardwachttijden aan om rekening te houden met onvoorspelbaarheid van de container.
- Gebruik Expliciete wachttijden: vertrouw op expliciete wachttijden die wachten op specifieke voorwaarden in plaats van impliciete wachttijden.
- Gezondheidscontroles: zorg ervoor dat de services operationeel zijn voordat de test wordt uitgevoerd.
- Logboeken en monitoring: houd gedetailleerde logboeken bij voor analyse van de hoofdoorzaak van fouten.
- Omgevingspariteit: koppel de Docker-omgeving aan de productie/enscenering om onverwacht gedrag tot een minimum te beperken.
- Netwerkproblemen oplossen: Gebruik hulpprogramma’s om op services te wachten of de netwerktime-outs te verlengen als netwerkgerelateerde fouten vaak voorkomen.
Door deze veelvoorkomende fouten te begrijpen en de beste praktijken te implementeren, kunt u de robuustheid en betrouwbaarheid van tests in containers verbeteren.
In het kort
Implicit Wait is een set-it-and-forget-it-mechanisme, maar kan leiden tot een tragere testuitvoering. Explicit Wait is dynamischer en conditiespecifieker, waardoor het geschikt is voor de meeste scenario’s in moderne webapplicaties. Fluent Wait biedt de meeste flexibiliteit en is het beste voor complexe scenario’s waarbij u een fijnmazige controle over de wachttijden en de polling-frequentie nodig hebt.
Wat webdriverio betreft, als je naar het webdriverio-concept kijkt via het ingebouwde wachtmechanisme, gebruiken ze van nature constant een vloeiend wachtmechanisme als je het wilt gebruiken.
Goed wachten op elementen of omstandigheden is cruciaal voor stabiele automatiseringstests. Of u nu WebDriverIO of Java Selenium gebruikt, het begrijpen en gebruiken van de juiste wachtstrategie kan het verschil maken tussen een flauwe test en een betrouwbare test.
Vergeet niet om altijd willekeurige, hard gecodeerde wachttijden te vermijden en in plaats daarvan te kiezen voor dynamische wachttijden die zich aanpassen aan het gedrag van de toepassing. Veel plezier met testen!
door Ralph Van Der Horst