Вопрос по java – Когда использовать явное ожидание против неявного ожидания в Selenium Webdriver?

39

Я использую:

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);
    }

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

Вы абсолютно уверены, что это не сNoSuchElementException? Это может потерпеть неудачу сWebDriverException, StaleElementReferenceException, ElementNotVisibleException или что-то подобное. Я попытаюсь угадать первый.Implicit wait ждет только пока не сработает функцияNoSuchElementExceptions ... Petr Janeček
Разница между методом явного ожидания Selenium и вашим кодом с помощью Thread.sleep () заключается в временных шагах: WebDriverWait проверяет наличие элементов каждые 500 миллисекунд, ваш код - 1000 миллисекунд. Aleh Douhi
Я должен использовать явное ожидание, так как это элемент AJAX SUM
Извиняюсь за то, что не констатировал ошибку. Это ElementNotVisibleExeption. Но видимое исключение элемента, на которое он жалуется, это какой-то другой элемент, на который нельзя щелкнуть, поскольку поле Имя пусто. Я добавлю явное поле ожидания для имени, поскольку это первое поле, над которым нужно работать на новой странице. SUM

Ваш Ответ

6   ответов
81

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

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

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

documented and defined behaviour. runs in the local part of selenium (in the language of your code). works on any condition you can think of. returns either success or timeout error. can define absence of element as success condition. can customize delay between retries and exceptions to ignore.

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

undocumented and practically undefined behaviour. runs in the remote part of selenium (the part controlling the browser). only works on find element(s) methods. returns either element found or (after timeout) not found. if checking for absence of element must always wait until timeout. cannot be customized other than global timeout.

Давайте посмотрим на разницу между явным ожиданием и неявным ожиданием в фактическом исходном коде селена. Я скопировал код из привязки python к селену, потому что python "легко читается".

КодWebDriverWait.until() (явное ожидание):

def until(self, method, message=''):
    end_time = time.time() + self._timeout
    while(True):
        try:
            value = method(self._driver)
            if value:
                return value
        except self._ignored_exceptions:
            pass
        time.sleep(self._poll)
        if(time.time() > end_time):
            break
    raise TimeoutException(message)

Теперь на человеческом языке: явное ожидание ожидает метод, который возвращает истинное значение в случае успеха. Затем он многократно выполняет данный метод с задержкой между ними. Ожидаемые ошибки от данного метода подавляются. Если данный метод возвращает истинное значение, то явное ожидание вернет это значение. Если время истекает, возникает исключение тайм-аута.

Сравните с кодомWebDriver.implicitly_wait() (комментарии удалены для краткости):

def implicitly_wait(self, time_to_wait):
    self.execute(Command.IMPLICIT_WAIT, {'ms': float(time_to_wait) * 1000})

self.execute() являетсяWebDriver.execute() какие звонкиRemoteConnection.execute() который, в свою очередь, делает, насколько я могу судить, RPC для удаленной стороны селена.

На человеческом языке: неявное ожидание отправляет сообщение на «удаленную сторону» веб-драйвера селена. Удаленная сторона селенового веб-драйвера является частью селена, которая фактически управляет браузером. Что делает удаленная сторона с сообщением? & quot; Это зависит & quot ;. Это зависит от операционной системы, браузера и версии селен. Насколько я могу судить, нет никакой гарантии относительно фактического поведения конкретной реализации.

Возможные реализации:

repeatedly try to find element until timeout. return as soon as element is found. try to find element. wait until timeout. try again. wait until timeout. try to find element.

Обратите внимание, что неявное ожидание вступает в силу только для методов find element (s).

Я не посмотрел фактический исходный код удаленных сторон селена. Информация собирается из чтения комментариев вошибка сообщает о неявном и явном ожидании в селене:

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

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

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

Official documentation (does not really explain the problematic other than warning from mixing implicit and explicit wait). Answer on a related question from Jim Evans. Jim Evans is a maintainer of selenium. Summary: don't mix implicit and explicit wait. Two blog posts explaining implicit and explicit wait in great detail: http://vnrtech.blogspot.de/2013/04/selenium-implicit-wait.html http://vnrtech.blogspot.de/2013/04/selenium-explicit-wait.html Selected bugs about implicit and explicit wait in selenium: http://code.google.com/p/selenium/issues/detail?id=2934 http://code.google.com/p/selenium/issues/detail?id=4471 http://code.google.com/p/selenium/issues/detail?id=7972
Я обнаружил, что неявное ожидание намного проще, особенно для роботов или сценариев автоматизации, которые работают локально. Я использовал как явное, так и неявное в двух разных проектах, и неявное было намного быстрее кодировать без повторения (СУХОЙ). Мне пришлось создать API для веб-приложения, у которого нет API! Единственной проблемой было тестирование на наличие элемента, которого там может не быть. Неявное ожидание все время, но я просто установил тайм-аут на 0 до проверки (в try / catch) и сбросил на 5 после. Это происходит гораздо реже, поэтому оно того стоит.
Разве явное ожидание не требует вдвое больше кода? Это довольно ужасный дизайн API.
4

Реализация интерфейса ожидания, для которого могут быть настроены время ожидания и интервал опроса на лету. Каждый экземпляр 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();

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

0

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

Syntax:

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

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

Syntax:

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

Implicit wait - Этоglobal setting применимо для всех элементов, и если элемент появится раньше указанного времени, скрипт начнет выполняться, иначе скрипт выдастNoSuchElementException, Лучший способ использовать в методе настройки. Влияет толькоBy.findelement().

Thread.sleep() - Это будет время сна для сценария,not good way использовать в сценарии, поскольку он спит без условий. Что если 2 секунд недостаточно в 5% случаев?

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

0

ImplicitWait :

    1.. UnConditional Wait. ( No Conditions were given)
    3. Applicable throughout the program

Declaring the implicit wait in java - selenium:

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

Explicit Wait:

Dynamic Wait Conditional Wait. Not applicable throughout the program

Declaring the Explicit Wait in Java Selenium.

WebDriverWait wait=new WebDriverWait(driver, 20); wait.until(somecondition);
Можете ли вы добавить ответ на актуальный вопрос: «когда использовать тот или иной»?
2

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

WebDriverWait _wait = new Web,DriverWait(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 :)

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

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

Уверены ли вы? Какие / где ошибки? Я думал, что я запускал это в моей собственной среде, и все было хорошо, поэтому буду благодарен за любые отзывы :)
Ах! Спасибо @JimEvans, вы правы, я привел очень подлый пример C #, мои извинения! Я помогал кому-то в другом потоке, который кодировал на C # и не очень тщательно проверял ваш синтаксис. Сегодня я попытаюсь обновить свой ответ на Java.
Например. имя метода - "findElement" не & quot; FindElement & quot ;. & Quot; = & GT; & Quot; не имеет смысла в контексте Java, в котором написан вопрос.
@JoshDiehl Код в ответе является совершенно правильным кодом C #. Следует признать, что было бы неплохо, если бы Нашибукасан упомянул об этом заранее и что эквивалентный код Java выглядел бы несколько иначе, но это не означает, что код является недействительным.
Пример кода имеет регистр и другие ошибки

Похожие вопросы