Имплицитно и експлицитно изчакване Selenium със синтаксис
⚡ Умно обобщение
Selenium Командите за изчакване синхронизират скриптовете за автоматизация с динамично поведение на страницата, предотвратявайки неуспехи на тестовете, причинени от елементи, които се зареждат асинхронно. Този справочник обяснява имплицитните, експлицитните и Fluent стратегиите за изчакване със синтаксис на WebDriver, които работят... Java примерни кодове и практически насоки за избор на подходящо изчакване за стабилно и надеждно изпълнение на тестове.
In Selenium„Изчакванията“ играят важна роля в изпълнението на надеждни тестове. В този урок ще научите ключовите аспекти и разлики между имплицитните и експлицитните команди за изчакване в Selenium, заедно с практическото използване на Fluent Wait.
Защо се нуждаем от чакане Selenium?
Повечето съвременни уеб приложения са разработени с помощта на Аякс намлява JavaСценарийКогато дадена страница се зарежда от браузъра, елементите, с които искаме да взаимодействаме, могат да се зареждат през различни интервали от време.
Това не само затруднява идентифицирането на елемента, но ако елементът не е локализиран във времето, Selenium ще хвърли ElementNotVisibleException. Selenium Функциите „waits“ решават този проблем със синхронизацията, като предоставят на WebDriver дефиниран прозорец, в който да намери елемент, преди да се получи неуспех.
Да разгледаме сценарий, в който в един и същ тест се използват както имплицитни, така и експлицитни изчаквания. Да приемем, че имплицитното изчакване е зададено на 20 секунди, а експлицитното изчакване е зададено на 10 секунди.
Ако търсим елемент, управляван от определени Очаквани условия (Изрично изчакване) и елементът не се намира в рамките на изричния прозорец от 10 секунди, WebDriver се връща към имплицитния прозорец от 20 секунди, преди да хвърли грешка ElementNotVisibleException.
Selenium WebDriver чака
- Неявно изчакайте
- Изрично изчакайте
- Свободно изчакайте
Неявно изчакване Selenium
- Неявно изчакване Selenium инструктира WebDriver да изчака определен период от време, преди да хвърли NoSuchElementException. Стойността по подразбиране е 0. След като бъде конфигуриран, WebDriver анкетира DOM през този период, преди да се провали. Selenium WebDriver наследи концепцията за имплицитно чакане от Watir.
В примера по-долу декларираме имплицитно изчакване с продължителност 10 секунди. Ако елементът не се намира в този прозорец, се генерира изключение.
Синтаксис на имплицитно чакане (Selenium 4):
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
package guru.test99;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;
public class AppTest {
protected WebDriver driver;
@Test
public void guru99tutorials() throws InterruptedException {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
String eTitle = "Demo Guru99 Page";
String aTitle = "";
// launch Chrome and redirect it to the Base URL
driver.get("https://demo.guru99.com/test/guru99home/");
// Maximize the browser window
driver.manage().window().maximize();
// get the actual value of the title
aTitle = driver.getTitle();
// compare the actual title with the expected title
if (aTitle.equals(eTitle)) {
System.out.println("Test Passed");
} else {
System.out.println("Test Failed");
}
// close browser
driver.close();
}
}
Обяснение на Code
В горния пример разгледайте следното твърдение:
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
Selenium Версия 4 замени по-старата сигнатура с два аргумента (цяло число плюс TimeUnit) с един аргумент Duration. Класът Duration поддържа секунди, минути, милисекунди и други времеви единици чрез статични помощни функции като Duration.ofSeconds, Duration.ofMillis и Duration.ofMinutes.
Изрично изчакване Selenium
- Изрично изчакване Selenium инструктира WebDriver да изчака специфични условия (Очаквани условия) или максимална продължителност, преди да хвърли ElementNotVisibleException. Това е по-интелигентно изчакване, защото се прилага само за посочения елемент. Изричното изчакване е за предпочитане пред имплицитното изчакване, когато тестът трябва да обработва динамично заредено Ajax съдържание.
След като е декларирано изрично чакане, трябва да използвате Очаквани условияили можете да конфигурирате честотата на запитване, използвайки Свободно изчакайтеИзбягвайте употребата Thread.sleep(), тъй като това спира изпълнението безусловно и обикновено се счита за лоша практика.
В примера по-долу създаваме препратка към WebDriverWait клас, създайте го с уебдрайвер справка и конфигурирайте максимален прозорец от 20 секунди.
Синтаксис на изрично чакане (Selenium 4):
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
package guru.test99;
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.Test;
public class AppTest2 {
protected WebDriver driver;
@Test
public void guru99tutorials() throws InterruptedException {
driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
String eTitle = "Demo Guru99 Page";
String aTitle = "";
// launch Chrome and redirect it to the Base URL
driver.get("https://demo.guru99.com/test/guru99home/");
// Maximize the browser window
driver.manage().window().maximize();
// get the actual value of the title
aTitle = driver.getTitle();
// compare the actual title with the expected title
if (aTitle.contentEquals(eTitle)) {
System.out.println("Test Passed");
} else {
System.out.println("Test Failed");
}
WebElement guru99seleniumlink;
guru99seleniumlink = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i")));
guru99seleniumlink.click();
}
}
Обяснение на Code
Разгледайте следния код:
WebElement guru99seleniumlink;
guru99seleniumlink = wait.until(ExpectedConditions.visibilityOfElementLocated(
By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i")));
guru99seleniumlink.click();
В този пример WebDriverWait, скриптът изчаква до 20 секунди, както е дефинирано от WebDriverWait клас, докато Очаквани условия са удовлетворени — което от двете настъпи първо.
Горното Java кодът чака до 20 секунди за условието видимостНаРазположенЕлемент за да е истина.
Следните очаквани условия могат да бъдат използвани в Selenium Изрично изчакване:
- alertIsPresent()
- elementSelectionStateToBe()
- elementToBeClickable()
- elementToBeSelected()
- frameToBeAvailableAndSwitchToIt()
- invisibilityOfTheElementLocated()
- invisibilityOfElementWithText()
- присъствиеНаВсичкиЕлементиLocatedBy()
- присъствиеОфЕлементLocated()
- textToBePresentInElement()
- textToBePresentInElementLocated()
- textToBePresentInElementValue()
- titleIs()
- titleContains()
- visibilityOf()
- visibilityOfAllElements()
- visibilityOfAllElementsLocatedBy()
- visibilityOfElementLocated()
Свободно Изчакайте Selenium
- Свободно Изчакайте Selenium дефинира максималната продължителност, през която WebDriver да чака условие, заедно с честотата на запитване за проверка на това условие, преди да се хвърли ElementNotVisibleException. Fluent Wait проверява за елемента на редовни интервали, докато обектът бъде намерен или изтече времето за изчакване.
Честота: Цикълът на повторение за оценка на състоянието през равни интервали.
Да разгледаме сценарий, в който елемент се зарежда на непредсказуеми интервали. Елементът може да се зареди за 10 секунди, 20 секунди или повече. Ако декларираме изрично изчакване от 20 секунди, скриптът ще изчака през цялото време, преди да се провали. В такива случаи Fluent Wait е идеалният избор, защото той извършва запитвания с указаната честота, докато елементът бъде локализиран или крайният таймер не изтече.
Синтаксис на плавно изчакване (Selenium 4):
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
По-старият подпис, който приемаше целочислени стойности плюс TimeUnit, беше остарял през Selenium 3.11 и премахнато в Selenium 4. Показаният по-горе API, базиран на продължителност, е текущо препоръчителният подход.
package guru.test99;
import java.time.Duration;
import java.util.NoSuchElementException;
import java.util.function.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.testng.annotations.Test;
public class AppTest3 {
protected WebDriver driver;
@Test
public void guru99tutorials() throws InterruptedException {
String eTitle = "Demo Guru99 Page";
String aTitle = "";
driver = new ChromeDriver();
// launch Chrome and redirect it to the Base URL
driver.get("https://demo.guru99.com/test/guru99home/");
// Maximize the browser window
driver.manage().window().maximize();
// get the actual value of the title
aTitle = driver.getTitle();
// compare the actual title with the expected title
if (aTitle.contentEquals(eTitle)) {
System.out.println("Test Passed");
} else {
System.out.println("Test Failed");
}
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
WebElement clickseleniumlink = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i"));
}
});
// click on the selenium link
clickseleniumlink.click();
// close browser
driver.close();
}
}
Обяснение на Code
Разгледайте следния код:
Wait<WebDriver> wait = new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(30))
.pollingEvery(Duration.ofSeconds(5))
.ignoring(NoSuchElementException.class);
В горния пример декларираме Fluent Wait с време за изчакване от 30 секунди, честота на запитване от 5 секунди и игнорираме NoSuchElementException.
Разгледайте следния код:
public WebElement apply(WebDriver driver) {
return driver.findElement(By.xpath("/html/body/div[1]/section/div[2]/div/div[1]/div/div[1]/div/div/div/div[2]/div[2]/div/div/div/div/div[1]/div/div/a/i"));
}
Тази функция идентифицира WebElement на страницата (тук, Selenium връзка на началната страница). С интервал на запитване от 5 секунди и време за изчакване от 30 секунди, скриптът за изчакване проверява за елемента на всеки 5 секунди за максимум 30 секунди. Ако елементът се намира в този прозорец, изпълнението продължава. В противен случай, ElementNotVisibleException е хвърлено.
Също така проверете: Selenium Урок за IDE за начинаещи
Разлика между имплицитно изчакване срещу явно изчакване
Таблицата по-долу подчертава ключовите разлики между имплицитно изчакване и експлицитно изчакване. Selenium.
| Неявно изчакайте | Изрично изчакайте |
|---|---|
| Имплицитното време за изчакване се прилага към всички елементи в скрипта. | Изричното време за изчакване се прилага само към конкретно насочените елементи. |
| В Implicit Wait, ExpectedConditions не са зададени за елемента. | В Explicit Wait, ExpectedConditions трябва да бъдат дефинирани за елемента. |
| Препоръчва се, когато елементите се заредят в рамките на конфигурирания имплицитен прозорец за изчакване. | Препоръчва се, когато зареждането на елементи отнема повече време и при валидиране на състояния на елементи, като например visibilityOfElementLocated, elementToBeClickable или elementToBeSelected. |
| Задава се веднъж и се прилага за жизнения цикъл на екземпляра на WebDriver. | Задава се за всеки елемент или за всяка проверка, осигурявайки по-фин контрол. |
Как да изберете правилната стратегия за изчакване
Изборът на правилната команда за изчакване влияе директно върху стабилността на скрипта и времето за изпълнение. Използвайте тази рамка за вземане на решения, за да изберете подходящата опция за всеки сценарий.
- Определете модела на натоварване: Проверете дали елементът се появява във фиксирано време, след Ajax отговор или на непредсказуеми интервали. Фиксираните натоварвания са подходящи за Implicit Wait, докато непредсказуемите натоварвания изискват Fluent Wait.
- Избягвайте смесването на имплицитни и експлицитни чакания: Комбинирането на двете може да доведе до неочаквани забавяния, тъй като по-дългото чакане може да доминира. Selenium Документацията препоръчва използването само на една стратегия на WebDriver сесия.
- По подразбиране за изрично изчакване за динамично съдържание: Когато страниците зависят от Ajax, условно рендиране или анимации, Explicit Wait с ExpectedConditions е насочен точно към важния елемент.
- Използвайте Fluent Wait за променливо време: Когато времето за зареждане на елементи варира между изпълненията, конфигурирайте Fluent Wait с интервал на запитване. Запитването намалява общото време на изчакване в сравнение с едно дълго изчакване.
- Заменете Thread.sleep: Твърдо кодираните режими на заспиване забавят тестовите пакети и скриват реални проблеми с времето. Заменете ги с условни изчаквания, за да поддържате изпълнението бързо и детерминистично.
- Стойности на времето за изчакване на настройката: Започнете с кратки таймаути (5–10 секунди) и ги увеличавайте само когато повреди показват наистина бавно зареждане. Дългите таймаути по подразбиране маскират регресиите в производителността.
- Запазете чаканията в помощните програми: Централизирайте логиката на изчакване в помощен клас, така че промените в политиката за изчакване да се прилагат в целия тестов набор.
Следвайки тази рамка, инженерите по автоматизация могат да изградят устойчиви скриптове, които се адаптират към реалното време на приложението, без да стават бавни или крехки.
Често срещани грешки, които трябва да се избягват с Selenium коледари
Дори опитните тестери попадат в малък набор от повтарящи се капани, когато работят с Selenium чака. Избягването на тези проблеми поддържа скриптовете бързи, детерминистични и лесни за поддръжка в различните екипи и среди.
Първата често срещана грешка е прекомерната употреба на Thread.sleep. Твърдо кодирана пауза принуждава скрипта да изчаква пълното време, независимо от действителната наличност на елементите, което увеличава общото време за изпълнение. Заменете такива паузи с Explicit или Fluent Wait, така че скриптът да продължи в момента, в който условието е изпълнено.
Втората грешка е смесването на имплицитни и експлицитни изчаквания в един и същ тест. Двата механизма могат да се комбинират, създавайки непредсказуеми таймаути, които са трудни за отстраняване на грешки. Изберете една стратегия за всяка сесия на WebDriver и я прилагайте последователно.
Трета грешка е задаването на твърде високи времена за изчакване „за всеки случай“. Дългите прозорци по подразбиране крият истински проблеми с производителността и забавят обратната връзка в конвейерите за непрекъсната интеграция. Започнете с кратки времена за изчакване и ги удължете само когато регистрационните файлове за грешки докажат, че съществува реален проблем с времето.
Също така проверете: Selenium Урок за начинаещи: Научете WebDriver за 7 дни

