Статьи

Селен ждет: неявный, явный, беглый и сон

Selenium ждет загрузки страницы, которая играет важную роль в ваших сценариях Selenium. Они помогают сделать их менее рыхлыми и более надежными. Selenium обеспечивает многократное ожидание, чтобы обеспечить адекватное ожидание или паузу в выполнении сценария в зависимости от определенных условий. Таким образом, вы гарантируете, что не получите неудачные сценарии при выполнении автоматизации тестирования с Selenium . В этом уроке мы будем объяснять типы ожидания и сна Selenium, примеры в реальном времени и сравнительное исследование. Давайте начнем с ответа на ключевой вопрос: «Почему мы должны использовать Selenium Waits?»

Зачем нам нужен Selenium Waits?

Большинство современных приложений построено на JavaScript или Ajax с использованием таких платформ, как React, Angular или любых других, для загрузки веб-элементов которых требуется определенное время при загрузке или обновлении этой страницы. Следовательно, в случае, если вы захотите найти в своем скрипте элемент, который еще не загружен на страницу, selenium выдаст вам сообщение « ElementNotVisibleException ».

Приведенный ниже фрагмент кода поможет вам продемонстрировать ту же проблему, что и при выполнении автоматического тестирования с Selenium. В этом фрагменте кода я использую пример easemytrip.com, где пользователь почты выбирает пункт назначения «От» и «До» с датой поездки, веб-приложение загружает необходимые данные о рейсе в течение определенного времени. В этом случае, не применяя ожидание, пользователь стремится забронировать первый рейс из списка. Теперь, поскольку страница еще не загружена, сценарию не удалось найти кнопку «Забронировать сейчас». В результате возникает исключение NoSuchElementException . Фрагмент кода и вывод консоли ниже:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
  
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor;
  
public class NoWaitImplemented {
  
    public static void main(String[] args) throws InterruptedException {
         
        System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
         
        WebDriver driver=new ChromeDriver();
         
        driver.manage().window().maximize();
         
         
        driver.get("https://www.easemytrip.com/");
         
        driver.findElement(By.id("FromSector_show")).sendKeys("Delhi", Keys.ENTER);
        driver.findElement(By.id("Editbox13_show")).sendKeys("Mumbai", Keys.ENTER);
        driver.findElement(By.id("ddate")).click();
        driver.findElement(By.id("snd_4_08/08/2019")).click();
        driver.findElement(By.className("src_btn")).click();
        driver.findElement(By.xpath("//button[text()='Book Now']")).click();
     
         
         
         
  
    }
  
}

Консольный вывод:

Я использовал XPath для поиска веб-элементов, используя скрипты для автоматизации тестирования с Selenium.

Подробнее: Полное руководство по использованию XPath в Selenium с примерами

Selenium ждет загрузки страницы, помогает в решении этой проблемы. Существуют различные типы ожиданий Selenium, такие как неявное ожидание и явное ожидание, которые обеспечивают загрузку элементов на страницу до их обнаружения скриптом Selenium для дальнейших действий.

Типы селена ждут загрузки страницы

При выполнении автоматизации тестирования с Selenium мы используем следующие типы ожидания при создании нашего сценария Selenium:

  • Метод Thread.Sleep ()
  • Неявное ожидание
  • Явное ожидание
  • Свободное ожидание

Давайте разберемся с каждым из них в деталях.

Thread.Sleep () для автоматизации тестирования с Selenium

Sleep — это статический метод, который принадлежит классу потока. Этот метод может быть вызван с использованием ссылки на имя класса, т.е. Thread. Если вы используете Thread.sleep при выполнении автоматического тестирования с помощью Selenium, этот метод остановит выполнение сценария на указанный промежуток времени, независимо от того, найден элемент на веб-странице или нет. Он принимает продолжительность в миллисекундах. Синтаксис для того же:

Thread.sleep(3000);

Функция сна генерирует InterruptedException, поэтому она должна обрабатываться с использованием блока try-catch, как показано ниже:

1
2
3
4
5
try{
Thread.sleep(5000);
}
catch(InterruptedException ie){
}

Почему использование Thread.Sleep () не является хорошей идеей?

Теперь я расскажу о некоторых недостатках использования thread.sleep ().

  • Selenium Webdriver ожидает указанное время, независимо от того, найден элемент или нет. В случае, если элемент найден задолго до указанной продолжительности, сценарий все еще будет ожидать истечения временной продолжительности, тем самым увеличивая время выполнения сценария.
  • Если присутствующий элемент не появляется после статического времени и продолжает изменяться, то вы никогда не узнаете примерное время, необходимое для функции сна. Если это займет больше времени, чем определенное время, скрипт выдаст ошибку. Вот почему, если вы имеете дело с динамическими элементами, использующими Selenium, то целесообразно не использовать Thread.sleep ().
  • Thread.sleep предназначен только для элемента, для которого он написан. Если у вас есть от двух до четырех элементов, которым нужно ждать определенную продолжительность для загрузки, вам нужно указать Thread.sleep столько раз, сколько в этом случае. И если ты это сделаешь! Ну, вы найдете ваш скрипт с синтаксисом Thread.sleep () повсюду.

Из-за вышеупомянутых недостатков использование Thread.Sleep () в вашем скрипте считается плохой практикой.

В приведенном ниже фрагменте кода показано использование Thread.Sleep () для автоматизации тестирования с помощью Selenium. В этом примере мы используем тот же пример easemytrip выше, где мы остановим выполнение потока, как только пользователь нажмет на поиск. В этом случае код работает плавно, без каких-либо ошибок.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
  
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor;
  
public class ThreadWait {
  
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
         
        //setting the driver executable
        System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
         
        //Initiating your chromedriver
        WebDriver driver=new ChromeDriver();
         
        driver.manage().window().maximize();
         
         
        driver.get("https://www.easemytrip.com/");
         
        driver.findElement(By.id("FromSector_show")).sendKeys("Delhi", Keys.ENTER);
        driver.findElement(By.id("Editbox13_show")).sendKeys("Mumbai", Keys.ENTER);
        driver.findElement(By.id("ddate")).click();
        driver.findElement(By.id("snd_4_08/08/2019")).click();
        driver.findElement(By.className("src_btn")).click();
        Thread.sleep(5000);
        driver.findElement(By.xpath("//button[text()='Book Now']")).click();
         
         
         
         
  
    }
  
}

А что если у меня есть другая страница того же приложения, которая загружается определенное время? В этом случае я не предпочел бы использовать thread.sleep () несколько раз в моем скрипте.

Вы можете подумать, что если не Thread.sleep (), то какой Selenium ожидает загрузки страницы, будет достаточным для тестирования?

Именно здесь в таких случаях приходит неявное ожидание. Позвольте нам оформить неявный Selenium, подождите подробно.

Неявное ожидание автоматизации тестирования с Selenium

Selenium преодолел проблемы, предоставляемые Thread.sleep (), и предложил два Selenium, ожидающих загрузки страницы. Одним из них является неявное ожидание, которое позволяет вам останавливать WebDriver на определенный период времени, пока WebDriver не найдет нужный элемент на веб-странице.

Ключевой момент, на который следует обратить внимание: в отличие от Thread.sleep (), он не ожидает полной продолжительности времени. В случае, если он находит элемент до указанной продолжительности, он переходит к следующей строке выполнения кода, тем самым сокращая время выполнения скрипта. Вот почему неявное ожидание также называется динамическим ожиданием. Если он не находит элемент в течение указанного времени, он генерирует исключение ElementNotVisibleException .

Еще одна интересная вещь, которую стоит отметить в отношении неявного ожидания, заключается в том, что он применяется глобально, что делает его лучшим вариантом, чем Thread.sleep (). Это означает, что вам нужно написать его только один раз, и он станет применимым для всех веб-элементов, указанных в сценарии в экземпляре WebDriver. Удобно, не так ли? Синтаксис для достижения того же:

1
driver.manage().timeouts().implicitlyWait(Time Interval to wait for, TimeUnit.SECONDS);

Время по умолчанию для неявного ожидания равно нулю, и оно продолжает опрашивать требуемый элемент каждые 500 миллисекунд. Давайте посмотрим на фрагмент кода ниже, демонстрирующий использование неявного ожидания. В этом примере я использую тот же пример easemytrip. В этом случае мы идем на шаг вперед и продолжаем процесс бронирования, при котором загрузка страницы занимает больше времени. Здесь проблема загрузки страницы существует для двух страниц, с которыми мы имеем дело, используя одну строку кода, используя неявное ожидание, а не несколько раз Thread.sleep ().

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
  
import com.gargoylesoftware.htmlunit.javascript.background.JavaScriptExecutor;
  
public class ImplicitWait {
  
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
         
        //setting the driver executable
        System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
         
        //Initiating your chromedriver
        WebDriver driver=new ChromeDriver();
         
        driver.manage().window().maximize();
         
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.get("https://www.easemytrip.com/");
         
        driver.findElement(By.id("FromSector_show")).sendKeys("Delhi", Keys.ENTER);
        driver.findElement(By.id("Editbox13_show")).sendKeys("Mumbai", Keys.ENTER);
        driver.findElement(By.id("ddate")).click();
        driver.findElement(By.id("snd_4_08/08/2019")).click();
        driver.findElement(By.className("src_btn")).click();
  
        driver.findElement(By.xpath("//button[text()='Book Now']")).click();
         
        JavascriptExecutor jse = (JavascriptExecutor)driver;
        jse.executeScript("window.scrollBy(0,750)");
         
        driver.findElement(By.xpath("//input[@type='email']")).sendKeys("[email protected]");
         
        driver.findElement(By.xpath("//span[text()='Continue Booking']")).click();
         
        WebElement title=driver.findElement(By.id("titleAdult0"));
         
        Select titleTraveller=new Select(title);
         
        titleTraveller.selectByVisibleText("MS");
        driver.findElement(By.xpath("//input[@placeholder='Enter First Name']")).sendKeys("Sadhvi");
        driver.findElement(By.xpath("//input[@placeholder='Enter Last Name']")).sendKeys("Singh");
         
        driver.findElement(By.xpath("//input[@placeholder='Mobile Number']")).sendKeys("9958468819");
         
        driver.findElement(By.xpath("//div[@class='con1']/span[@class='co1']")).click();
         
  
    }
  
}

Теперь, здесь мы знаем о том факте, что страницы должны загружаться в течение определенного периода времени, но что, если мы не знаем, какой элемент должен быть видимым / кликабельным во время загрузки. Как и во время его появления динамично и постоянно меняется время от времени. В этом случае явное ожидание поможет вам преодолеть эту проблему. Давайте рассмотрим его подробно.

Явное ожидание автоматизации тестирования с Selenium

Явное ожидание — это еще одно из динамических ожиданий Selenium. Явная помощь в ожидании, чтобы остановить выполнение сценария на основе определенного условия в течение указанного периода времени. Как только время уйдет за борт, вы получите исключение ElementNotVisibleException . В сценарии, когда вы не знаете, сколько времени ждать, это явное ожидание пригодится. Используя такие условия, как elementToBeClickable () или textToBePresentInElement () , можно дождаться указанной продолжительности. Можно использовать эти предопределенные методы, используя комбинацию классов WebDriverWait и ExpectedConditions. Чтобы использовать этот случай, импортируйте следующие пакеты в свой класс:

1
2
import org.openqa.selenium.support.ui.ExpectedConditions
import org.openqa.selenium.support.ui.WebDriverWait

После этого необходимо создать ссылочную переменную для класса WebDriverWait и создать его экземпляр с помощью экземпляра WebDriver и предоставить количество Selenium, ожидающих загрузки страницы, в которых может потребоваться. Единица времени в секундах. Можно определить это как ниже:

1
WebDriverWait wait = new WebDriverWait(driver,30);

Чтобы использовать предопределенные методы класса ExpectedCondition, мы будем использовать ссылочную переменную ожидания, как показано ниже:

1
wait.until(ExpectedConditions.visibilityOfElementLocated(Reference of Element to be  located using locator));

Типы ожидаемых условий:

Ниже приведены несколько типов ожидаемых условий, которые обычно используются при выполнении автоматического тестирования с помощью Selenium.

  • visibilityOfElementLocated () — Проверяет, присутствует ли данный элемент или нет
  • alertIsPresent () — Проверяет, присутствует ли оповещение или нет.
  • elementToBeClickable () — Проверяет, присутствует ли данный элемент / кликабелен ли он на экране
  • textToBePresentInElement () — Проверяет, имеет ли данный элемент необходимый текст или нет
  • titlels () — проверка условия ожидания для страницы с заданным заголовком

Есть много других ожидаемых условий, о которых вы можете узнать на официальной странице Selenium GitHub . Как и неявное ожидание, явное ожидание также продолжает опрос после каждых 500 миллисекунд.

Ниже приведен фрагмент кода, освещающий использование явного ожидания Selenium. В этом примере мы используем приложение rentomojo, где модальное время появляется на главной странице в динамическое время. Используя явное ожидание, основанное на видимости элемента, мы дождемся элемента и закроем всплывающее окно. Код ссылки:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import java.util.concurrent.TimeUnit;
  
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
  
public class ExplicitWait {
  
    public static void main(String[] args) {
        // TODO Auto-generated method stub
         
        //setting the driver executable
                System.setProperty("webdriver.chrome.driver", ".\\Driver\\chromedriver.exe");
                 
                //Initiating your chromedriver
                WebDriver driver=new ChromeDriver();
                 
                 
                 
                driver.manage().window().maximize();
                 
                driver.get("https://www.rentomojo.com/");
                 
                driver.findElement(By.xpath("//span[@class='rm-city__selectorBoxLoca'][contains(text(),'Delhi')]")).click();
                 
                 
                 
                WebDriverWait wait=new WebDriverWait(driver, 120);
                 
                 
                wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//div[@class='Campaign__innerWrapper']/button"))));
                driver.findElement(By.xpath("//div[@class='Campaign__innerWrapper']/button")).click();
  
    }
  
}

Примечание. Когда неявное ожидание и явное ожидание даются совместно, они работают на совокупное время, а не на одно условие ожидания. Например, если неявное ожидание дается на 30 секунд, а явное ожидание дается на 10 секунд, то искомый элемент, который он ищет, будет ожидать 40 секунд.

Разница между селеновым ожиданием: явное и неявное

Теперь, поскольку вы знаете об использовании неявных и явных ожиданий, давайте рассмотрим разницу между этими двумя ожиданиями Selenium:

Неявное ожидание

Явное ожидание

По умолчанию он применяется ко всем элементам скрипта. Это применимо только к определенному элементу, который является определенным для определенного условия.
Мы не можем ждать, основываясь на указанном условии, таком как элемент selectable / clickable в отличие от явного. В явном виде мы можем указать ожидание на основе конкретного условия.
Обычно используется, когда вы уверены, что элемент может быть виден в определенное время Обычно используется, когда вы не знаете время видимости элемента. Он подвержен динамическому характеру.

Свободное ожидание автоматизации тестирования с селеном

Беглое ожидание похоже на явное ожидание с точки зрения его функционирования. В режиме «Свободное ожидание» вы выполняете ожидание Selenium для элемента, когда вы не знаете, сколько времени может потребоваться, чтобы его можно было увидеть или щелкнуть. Несколько отличительных факторов, которые предлагает Свободное ожидание:

  • Частота опроса — в случае явного ожидания эта частота опроса по умолчанию составляет 500 миллисекунд. Используя свободное ожидание, вы можете изменить частоту опроса в соответствии со своими потребностями, то есть вы можете указать своему сценарию проверять элемент после каждых «х» секунд.
  • Игнорировать исключение — во время опроса, если вы не нашли элемент, вы можете игнорировать любое исключение, такое как исключение «NoSuchElement» и т. Д.

Помимо этих дифференциальных факторов, таких как явное ожидание или неявное ожидание, вы можете определить время ожидания, пока элемент будет видимым или активным. Приведенный ниже синтаксис или строки кода используются для определения плавного ожидания в Selenium:

1
2
3
4
5
6
7
8
Wait<WebDriver> fluentWait = new FluentWait<WebDriver>(driver)
       .withTimeout(60, SECONDS) // this defines the total amount of time to wait for
       .pollingEvery(2, SECONDS) // this defines the polling frequency
       .ignoring(NoSuchElementException.class); // this defines the exception to ignore
      WebElement foo = fluentWait.until(new Function<WebDriver, WebElement>() {
     public WebElement apply(WebDriver driver)  //in this method defined your own subjected conditions for which we need to wait for
     {  return driver.findElement(By.id("foo"));
}});

Синтаксис выглядит сложным, но как только вы начнете использовать, он может стать удобным. Вероятно, это одна из главных причин, по которой тестеры предпочитают явное ожидание, а не свободное ожидание. Кроме того, основное различие между явным ожиданием и свободным ожиданием состоит в том, что явное ожидание селена предоставляет предопределенные условия, которые применяются к элементам, которые мы должны ожидать, тогда как в случае ожидания плавного селена вы можете определить свои собственные настроенные условия в рамках применяемого метода.

Мое мнение о Fluent Selenium Wait?

Лично я не нашел никакой полезной реализации плавного ожидания в примере в реальном времени, поэтому хотел бы воздержаться от его реализации, как сейчас. Я так же, как и вы, готов к запуску Selenium 4 . Я надеюсь, что после запуска мы сможем лучше понять практическое преимущество использования Fluent wait по сравнению с другими ожиданиями Selenium. До сих пор, основываясь на моем опыте, я склоняюсь к использованию явного ожидания Selenium, благодаря более простой реализации кода, чем Fluent Selenium wait. Если вы чувствуете иначе, то дайте мне знать в комментариях ниже.

Роль Selenium ждет облачной Selenium Grid

Большинство тестировщиков обычно предпочитают проводить автоматическое тестирование веб-сайтов, используя поставщика облачных услуг для тестирования Selenium, такого как LambdaTest, инструмент для кросс-браузерного тестирования в облаке. Интересно, почему?

Так что же произойдет, если вы запустите свои сценарии автоматизации на облачной Selenium Grid, такой как LambdaTest? Как Selenium Waits может способствовать эффективному результату теста?

Каждый облачный провайдер будет предлагать ограничение времени по умолчанию, прежде чем выдавать исключение Selenium Timeout. Это сделано для предотвращения чрезмерной эксплуатации облачных ресурсов. На LamdaTest вы получаете тайм-аут по умолчанию в 90 секунд. Теперь, если ваше время загрузки веб-элементов превышает 90 секунд, что вы можете сделать?

Вот тут-то и появляется Selenium wait. Если ваш набор тестов является сложным, который может столкнуться с проблемой тайм-аута в облачной Selenium Grid, тогда вы можете использовать Selenium wait, чтобы приостановить работу WebDriver на более чем 90 секунд по умолчанию. Таким образом, избежать ошибки тайм-аута при успешном запуске сценария автоматизации.

Окончательный вердикт о Selenium ждет!

Selenium Waits помогает сделать ваши скрипты менее надёжными и надёжными. Независимо от того, какое ожидание вы выберете, убедитесь, что оно поможет вам достичь цели автоматизации тестирования с помощью Selenium. Еще одна ключевая вещь, которую стоит отметить, — это не хранить ненужные ожидания Selenium в вашем приложении. Thread.sleep (), возможно, был опцией в прошлом, но теперь, когда у нас есть новый Selenium, ожидающий и готовящий, я бы лучше порекомендовал вам отвести тестирование автоматизации Selenium от Thread.sleep (). Итак, в следующий раз, когда вы столкнетесь с проблемой загрузки элементов или элементов, вы будете знать, где искать. Удачного тестирования!

Смотрите оригинальную статью здесь: Selenium Waits: неявный, явный, беглый и сон

Мнения, высказанные участниками Java Code Geeks, являются их собственными.