Когда использовать явный wait vs implicit wait в Selenium Webdriver?

Я использую:

driver.manage().timeouts().implicitlyWait(180, TimeUnit.SECONDS);

Но он все еще не работает непрерывно для нижнего элемента

    driver.findElement(By.id("name")).clear();
    driver.findElement(By.id("name")).sendKeys("Create_title_01");

Я добавил код ожидания:

for (int second = 0;; second++) {
        if (second >= 120) fail("timeout");
        try { if (isElementPresent(By.id("name"))) break; } catch (Exception e) {}
        Thread.sleep(1000);
    }

Не следует ли подразумевать ожидание, ожидая, пока элемент не будет найден? Также было бы лучше, если бы я использовал Explicit wait вместо кода, который я добавил, который имеет Thread.sleep()?

Ответ 1

TL; DR: всегда использовать явное ожидание. Забудьте, что неявное ожидание существует.


Вот краткое изложение различий между явным и неявным ожиданием:

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

  • задокументированное и определенное поведение.
  • работает в локальной части selenium (на языке вашего кода).
  • работает в любых условиях, о которых вы только можете подумать.
  • возвращает ошибку либо успеха, либо тайм-аута.
  • можно определить отсутствие элемента как условие успеха.
  • можно настроить задержку между попытками и исключениями, чтобы игнорировать.

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

  • недокументированное и практически неопределенное поведение.
  • работает в удаленной части selenium (часть, управляющая браузером).
  • работает только с методами поиска элементов.
  • возвращает либо элемент найден, либо (после тайм-аута) не найден.
  • при проверке отсутствия элемента всегда нужно ждать до истечения времени ожидания.
  • не может быть настроен, кроме глобального тайм-аута.

Примеры кода с пояснениями. Первое неявное ожидание:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

Теперь явное ожидание:

WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement myDynamicElement = wait.until(
  ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));

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

Пример возможных условий: elementToBeClickable, numberOfElementsToBeMoreThan или invisibilityOf. Вот список встроенных ожидаемых условий: https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html

Больше объяснений:

Неявное время ожидания влияет только на методы findElement*. Если установлено, все findElement* будут "ждать" установленное время, прежде чем объявить, что элемент не может быть найден.

Как findElement* будет ждать, не определено. Это зависит от браузера или операционной системы или версии селена. Возможные реализации:

  • неоднократно пытаться найти элемент до истечения времени ожидания. вернуть, как только элемент будет найден.
  • попытаться найти элемент. подождите до истечения времени ожидания попробуйте еще раз.
  • подождите до истечения времени ожидания попытаться найти элемент.

Этот список составлен из наблюдений и чтения отчетов об ошибках и краткого чтения исходного кода селена.


Мой вывод: неявное ожидание это плохо. Возможности ограничены. Поведение недокументировано и зависит от реализации.

Явное ожидание может делать все, неявное ожидание может и многое другое. Единственный недостаток явного ожидания - немного более подробный код. Но это многословие делает код явным. И явное лучше, чем неявное. Правильно?


Дальнейшее чтение:

Ответ 2

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

см. эту ссылку свободное описание ожидания

В частности, я использовал свободное ожидание таким образом:

public WebElement fluentWait(final By locator){
        Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                .withTimeout(30, TimeUnit.SECONDS)
                .pollingEvery(5, TimeUnit.SECONDS)
                .ignoring(NoSuchElementException.class);

        WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
            public WebElement apply(WebDriver driver) {
                        return driver.findElement(locator);
                }
                }
);
                           return  foo;              }     ;

Как вы заметили, беглое ожидание возвращает найденный веб-элемент. Таким образом, вы просто передаете локатор по типу By, а затем можете выполнять любые действия с найденным веб-элементом.

fluentWait(By.id("name")).clear();

Надеюсь, это поможет вам)

Ответ 3

Неявное ожидание - это глобальная настройка, применимая ко всем элементам, и если элемент появится до указанного времени, чем script, то запуск будет выполняться иначе script будет бросать NoSuchElementException, Лучший способ использования в методе настройки. Используйте только By.findelement().

Thread.sleep() - будет спать время script, не очень хорошо, чтобы использовать его в script, поскольку он спит без каких-либо условий. Что делать, если в 5% случаев недостаточно 2 секунд?

Явное ожидание: Подождите, пока не укажет, содержит/изменяет атрибут. Больше используется, когда приложение предоставляет AJAX вызов в систему и получает динамические данные и визуализацию в пользовательском интерфейсе. В этом случае подходит WebDriverWait.

Ответ 4

ImplicitWait:

    1. Static Wait 
    2. UnConditional Wait (No conditions are given)
    3. Applicable throughout the program

Объявление неявного ожидания в Java - Selen:

driver.manage().timeout().implicitWait(20, TimeUnit.Seconds());

Когда использовать неявный Wait?

Неявное ожидание не рекомендуется использовать где-либо в пакете автоматизации, поскольку это статично, и мы не знаем, когда веб-элемент появится на веб-сайте.

то есть. Допустим, вы установили неявное ожидание на 5 секунд, и драйвер может идентифицировать веб-элемент за 2 секунды, так как мы применили драйвер неявного ожидания, который будет ждать еще 3 секунды (до 5 секунд). Это замедлит процесс автоматизации.

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

  1. Динамическое ожидание
  2. Условное ожидание.
  3. Не применимо на протяжении всей программы

Объявление явного ожидания в Java Selenium.

WebDriverWait wait=new WebDriverWait(driver, 20); wait.until(somecondition);

Когда использовать явное ожидание?

Мы всегда должны использовать явное ожидание, так как оно носит динамический характер.

то есть. Допустим, вы установили явное ожидание 5 секунд, и драйвер может идентифицировать веб-элемент за 2 секунды, поскольку мы применили драйвер явного ожидания, который не будет ждать еще 3 секунды (до 5 секунд). Драйвер продолжит работу через 2 секунды. Это ускорит процесс автоматизации.

Ответ 5

Вы пытались использовать 'WebDriverWait'? Я представляю, что вы хотите:

WebDriverWait _wait = new WebDriverWait(driver, new TimeSpan(0, 0, 2)); //waits 2 secs max
_wait.Until(d => d.FindElement(By.Id("name")));
//do your business on the element here :)

Это в значительной степени будет, насколько я понимаю, делать то, что ваш текущий код. Он будет постоянно проверять метод (игнорируя не найденные исключения) до тех пор, пока не будет достигнут тайм-аут пройденного в промежутке времени, и третий параметр может быть введен для указания сна в миллисекундах. Извините, если это то, что implicitlyWait делает тоже!

Изменить: я прочитал сегодня и лучше понимаю ваш вопрос и понимаю, что это делает именно то, что должно делать ваша установка неявного ожидания. Оставим его здесь на всякий случай, если сам код может помочь кому-то другому.

Ответ 6

Неявные ожидания используются для обеспечения времени ожидания (скажем, 30 секунд) между каждым последовательным этапом тестирования по всему тесту script или программе. Следующий шаг выполняется только после истечения 30 секунд (или любого другого времени) после выполнения предыдущего шага

Синтаксис:

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

Явные ожидания используются для остановки выполнения до тех пор, пока не будет выполнено определенное условие или не будет определено максимальное время, которое определено. Неявное ожидание применяется между каждым последовательным этапом тестирования по всему тесту script или программам, тогда как явные ожидания применяются только для конкретного экземпляра.

Синтаксис:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver,30);