Способы ожидания в Java и Selenium
Обзор опций для написания ожиданий в автотестах, которые помогут организовать их работу в удобной форме.
56К открытий65К показов
Рассказывает Валерия, QA Automation Engineer в Noveo
Ожидания — не самый приятный процесс, где бы он ни происходил. Ожидания в автотестах — отдельная боль. Избавиться от них невозможно, но есть способы организовать их работу в более удобной форме, нежели Thread.sleep()
.
Чтобы собрать вместе и систематизировать информацию по этой теме, рассмотрю все варианты написания ожиданий для автоматизированного тестирования UI посредством Java и Selenium, с которыми мне приходилось работать, а именно ожидания, предоставляемые Selenium, возможность написания собственных ожиданий и библиотека Awaitility.
Selenium waiting methods
Implicit Wait
Implicit Wait, или неявное ожидание, — пожалуй, самый популярный способ ожидания в Selenium благодаря своей легкости в использовании.
Чтобы использовать Implicit Wait в автотестестах, достаточно:
- установить его всего 1 раз,
- указать вручную лимит ожидания.
После того, как команда исполнится, Implicit Wait будет действовать на протяжении всего пробега автотестов и ожидать указанное время прежде, чем выбросить NoSuchElementException
(или не выбрасывать, если необходимый элемент на странице найден). Не устанавливать Implicit Wait равносильно нулевому лимиту времени, и исключение пробросится сразу.
Чтобы установить Implicit Wait, необходимо написать всего одну строку после установки драйвера, и таким образом мы установим лимит ожидания 10 секунд:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Implicit Wait можно использовать для:
- ожидания полной загрузки страницы —
pageLoadTimeout()
; - ожидания появления элемента на странице —
implicitlyWait()
; - ожидания выполнения асинхронного запроса —
setScriptTimeout()
;
Установка использования неявного ожидания будет выглядеть следующим образом:
Explicit Wait
Explicit wait, или явное ожидание, чаще используется для ожидания определенного условия, которое должно быть выполнено прежде, чем тест пойдет дальше.
О явном ожидании стоит помнить следующие вещи:
- ожидание сработает именно там, где оно указано;
- как и неявному ожиданию, ему необходимо указать лимит времени;
- ожидает выполнения необходимого условия;
- ждет завершения Ajax request.
Использовать явное ожидание можно через WebDriverWait
. Инициализация будет происходить следующим образом:
WebDriverWait wait = new WebDriverWait(driver,10);
где driver
является референсом к нашему используемому WebDriver
, а число 10 — TimeOut
в секундах.
В тесте само ожидание уже будет выглядеть примерно так:
Класс ExpectedConditions
предоставляет нам ряд вещей, которых мы можем дожидаться во время пробега теста. Они все достаточно легко читаемы, что облегчит жизнь как вам, так и людям, которым, возможно, придется поддерживать ваши автотесты.
Вот полный список всего, что вам предлагает подождать ExpectedConditions
:
alertIsPresent()
elementSelectionStateToBe()
elementToBeClickable()
elementToBeSelected()
frameToBeAvaliableAndSwitchToIt()
invisibilityOfTheElementLocated()
invisibilityOfElementWithText()
presenceOfAllElementsLocatedBy()
presenceOfElementLocated()
textToBePresentInElement()
textToBePresentInElementLocated()
textToBePresentInElementValue()
titleIs()
titleContains()
visibilityOf()
visibilityOfAllElements()
visibilityOfAllElementsLocatedBy()
visibilityOfElementLocated()
В тесте создание и использование неявного ожидания будут выглядеть следующим образом:
Разница между Implicit и Explicit Wait
Написание собственных ожиданий
Ожидания Selenium не всегда способны удовлетворить потребности тестировщика. В таких случаях мы можем сами написать методы, которые удержат автотесты от падения. Работать кастомные ожидания будут по тому же принципу, что и Explicit Wait, т.е. срабатывать в той части теста, в которой указаны, а условие, которого необходимо дождаться, нужно написать самим как некий аналог класса ExpectedConditions
. Хранить ли свои условия в отдельном классе или в том же, где и написанный способ ожидания, и нужно ли разделять метод ожидания и условие или достаточно будет оставить их прописанными в едином методе, зависит от условий проекта и предпочтений тестировщика.
Чтобы написать ожидание самим, потребуется не так много: старый добрый цикл while и System.currentTimeMillis()
.
Выглядеть это может примерно таким образом:
Условие, которое мы ждем в этом примере — element.isDisplayed()
, его можно вынести в отдельный метод, возвращающий boolean
, и таким образом сам метод ожидания можно прописать единожды и просто передавать туда разные условия в формате boolean
.
Awaitility library
Пожалуй, лучшее, ну или, по крайней мере, мое любимое, решение проблемы ожиданий. Awaitility применима не только в автоматизации тестирования, однако я ограничусь рассмотрением ее использования на примерах тестов. Эта библиотека упростит вам жизнь при написании собственных ожиданий; все, что сказано про аналог кастомных ожиданий с Explicit Wait и ExpectedConditions
, будет справедливо и здесь. То же касается и того, как вы предпочтете прописать условия, которых хотите дождаться. В рамках этой статьи рассмотрена только часть возможностей данной библиотеки. Если вам интересно почитать обо всех возможностях, можете ознакомиться с официальной документацией. Здесь я хочу обратить внимание на те моменты, которые мне показались максимально полезными, и просто поделиться тем, что есть такая замечательная штука, которая помогает стабилизировать автотесты.
Awaitility library позволит:
- дождаться выполнения асинхронных запросов;
- установить как максимум, так и минимум ожидаемого времени;
- проигнорировать выпадающие исключения (в таком случае по истечению лимита времени будет выброшен
ConditionTimeoutException
); - использовать
Assertion
в качестве ожидаемого условия; - использовать polling.
Синтаксис довольно читабельный; Awaitility позволяет понять, что и куда вызывается для определения лимита времени, игнорирования исключений, где устанавливаем polling и чего ожидаем в финале нашего метода. Внутреннее написание ожидания может выглядеть так — остается только вызвать его в тесте. Хранить подобные методы стоит все же отдельно от тестов.
Отдельным примером хочу показать ожидание Assertion, именно этот метод кажется мне особенно удобным, так как убивает сразу двух зайцев и позволяет не прописывать лишних строк кода:
Это та информация, которой я хотела поделиться об ожиданиях.
Более подробно вы можете ознакомиться с Awaitility по ссылке.
56К открытий65К показов