Неявне та явне очікування Selenium з синтаксисом
⚡ Розумний підсумок
Selenium Команди очікування синхронізують скрипти автоматизації з динамічною поведінкою сторінки, запобігаючи збоям тестування, спричиненим елементами, що завантажуються асинхронно. У цьому посібнику пояснюються стратегії неявного, явного та вільного очікування з синтаксисом WebDriver, які працюють Java зразки коду та практичні поради щодо вибору відповідного часу очікування для стабільного та надійного виконання тестів.

In Selenium«Очікування» відіграють важливу роль у виконанні надійних тестів. У цьому посібнику ви дізнаєтеся про ключові аспекти та відмінності між неявними та явними командами очікування. Selenium, а також практичне використання Fluent Wait.
Чому нам потрібні очікування Selenium?
Більшість сучасних веб-додатків розробляються з використанням Ajax та JavaScriptКоли браузер завантажує сторінку, елементи, з якими ми хочемо взаємодіяти, можуть завантажуватися з різними інтервалами часу.
Це не тільки ускладнює ідентифікацію елемента, але й якщо елемент не локалізовано в часі, Selenium кине ElementNotVisibleException. Selenium Очікування вирішує цю проблему синхронізації, надаючи WebDriver визначене вікно, в якому потрібно знайти елемент перед помилкою.
Розглянемо сценарій, у якому в одному тесті використовуються як неявні, так і явні очікування. Припустимо, що неявне очікування встановлено на 20 секунд, а явне — на 10 секунд.
Якщо ми шукаємо елемент, що регулюється певними Очікувані умови (Явне очікування), і елемент не знаходиться в межах явного вікна 10 секунд, WebDriver повертається до неявного вікна 20 секунд, перш ніж викликати помилку. ElementNotVisibleException.
Selenium Очікування веб-драйвера
- Неявне очікування
- Явне очікування
- Вільно зачекайте
Неявне очікування 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()
- присутністьВсіхЕлементів, розташованих()
- присутністьОфЕлементРозташований()
- 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.
| Неявне очікування | Явне очікування |
|---|---|
| Неявний час очікування застосовується до всіх елементів у скрипті. | Явний час очікування застосовується лише до спеціально визначених елементів. |
| У неявному очікуванні очікувані умови для елемента не вказані. | У явному очікуванні для елемента мають бути визначені очікувані умови (ExpectedConditions). |
| Рекомендовано, коли елементи завантажуються в межах налаштованого неявного вікна очікування. | Рекомендовано, коли елементи завантажуються довше, а також під час перевірки станів елементів, таких як visibilityOfElementLocated, elementToBeClickable або elementToBeSelected. |
| Встановлюється один раз та застосовується протягом життєвого циклу екземпляра WebDriver. | Встановлюється для кожного елемента або перевірки, що забезпечує точніший контроль. |
Як вибрати правильну стратегію очікування
Вибір правильної команди очікування безпосередньо впливає на стабільність скрипта та час його виконання. Використовуйте цю структуру рішень, щоб вибрати відповідний варіант для кожного сценарію.
- Визначте схему навантаження: Перевірте, чи з'являється елемент у фіксований час, після відповіді Ajax чи через непередбачувані інтервали. Фіксовані навантаження підходять для неявного очікування, тоді як непередбачувані навантаження вимагають вільного очікування.
- Уникайте змішування неявного та явного очікування: Поєднання двох цих факторів може призвести до неочікуваних затримок, оскільки довше очікування може домінувати. 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 днів
