Тесты в Selenium, несомненно, выполняются быстрее, чем вручную. Однако даже автотесты, написанные с помощью Selenium, могут выполняться довольно медленно.
Если сравнивать с интеграционным и модульным тестированием, автоматизированные тесты Selenium уступают им по скорости. Иногда выполнение отдельных автотестов занимает даже несколько минут, что замедляет весь процесс. Когда количество таких тестов растет, это затрудняет получение быстрой обратной связи.
К счастью, существует множество способов ускорить автотесты Selenium для тестовых сценариев. В их числе – использование веб-локаторов и явных ожиданий, оптимизация инфраструктуры Selenium и многое другое. Все это можно сделать для улучшения работы ПО.
Содержание
Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ
Что могут делать автотесты Selenium?
- Используя удаленный (remote) веб-драйвер Selenium, открыть URL, который нужно протестировать
- Используя соответствующие локаторы Selenium (например, текст ссылки, xpath, css-селектор и т.д.), найти нужные веб-элементы.
- На найденных экземплярах WebElement выполнить все необходимые действия.
- Взаимодействовать с Webdriver, используя инструменты с открытым исходным кодом (т.е. бесплатные).
Как выполнять Selenium-тесты быстрее?
Мы не можем игнорировать производительность тестовых сценариев Selenium, поэтому стоит с самого начала позаботиться об ускорении их выполнения. Необходимо оптимизировать тестовую инфраструктуру Selenium, чтобы увеличить скорость выполнения тестовых сценариев. Ниже приведены различные способы ускорить автотесты Selenium.
Выбор правильных веб-локаторов
Веб-локаторы являются базовыми кирпичиками для тестового сценария.Чтобы автоматизировать взаимодействие с любым из веб-элементов, мы используем веб-локатор для определения его местоположения, а затем выполняем необходимые действия.
Примечание редакции: также предлагаем почитать статью “Как работать с WebElements в Selenium Python”.
Вместе с методами find_elements
или find_element
используются различные веб-локаторы. Теперь возникает вопрос: какие из них быстрее находят элементы?
Что касается скорости, то из всех веб-локаторов самым быстрым является id
. Этот ID-локатор вернет вам веб-элемент, совпадающий с заданной строкой (или указанным значением). Если на странице документа под одним ID содержится более одного элемента, getElementByID()
вернет первое совпадение.
Метод document.getElementById()
оптимизирован многими веб-браузерами, что позволяет находить веб-элементы быстрее, чем DOM (Document Object Model).
Если веб-элемент не имеет атрибута ID, то предлагается выбрать атрибут name.
Если веб-элемент не имеет ни атрибута id, ни атрибута name, то его можно найти по CSS-селектору. CSS-движок работает примерно одинаково во всех основных браузерах, а это означает минимум проблем с совместимостью браузеров.
CSS-селектор сокращает время выполнения и быстрее идентифицирует элемент. Это наилучший выбор локатора для старых браузеров, таких как Internet Explorer. По сравнению с XPath, CSS-селектор обеспечивает лучшую читаемость. При переходе от одного браузера к другому XPath может вызвать проблемы с совместимостью, кроме того, XPath известен как самый медленный веб-локатор. Его рекомендуется только если у вас нет другого надежного веб-локатора.
Веб-локаторы, от самого шустрого до самого медленного:
- id
- name
- css selector
- xpath
Использование меньшего количества веб-локаторов
Предположим, вы уже выбрали веб-локаторы. Следующим шагом будет сведение их количества к минимуму.
Каждый раз, когда вы используете find_elements(By)
или find_element(By)
для определения местоположения веб-элемента, выполняется обращение к DOM. По мере увеличения количества обращений к дереву DOM на выполнение скрипта Selenium будет требоваться все больше времени.
Поэтому лучшая практика – использовать как можно меньше веб-локаторов в Selenium при тестировании веб-приложений. Это поможет повысить читабельность теста и таким образом упростить поддержку написанных скриптов.
Полный запрет для Thread.sleep( )
Содержимое веб-приложения по своей природе может быть как динамическим, так и статическим.
Для динамической загрузки содержимого веб-страницы на сайтах используется AJAX (Asynchronous Javascript and XML), в результате чего элементы подгружаются на страницу через разные промежутки времени. Это создает трудности при выполнении операций над элементами, которых нет в DOM.
Отслеживая состояние document.readyState
, можно проверить состояние DOM. Подразумевается, что когда статус document.readyState
имеет значение “complete” (завершенный), то все ресурсы на странице загружены. После этого над веб-элементами, присутствующими на странице, можно выполнять требуемые операции.
Ожидание некоторого промежутка времени в коде теста увеличивает задержку, необходимую для загрузки ресурсов, присутствующих на странице. Существуют различные методы добавления ожидания в Selenium. При этом вы должны любой ценой избегать Thread.sleep()
. Это статический метод на языке Java, который ставит выполнение кода на паузу на определенное время. Подобный метод sleep()
есть и в других языках программирования.
Предположим, мы с помощью этого метода добавили ожидание в течение 5 секунд. Таким образом, если элемент загрузится раньше заданного времени (например, за 2 секунды), то оставшиеся 3 секунды увеличат общее время выполнения.
Время загрузки страницы зависит от различных внешних факторов, таких как пропускная способность сети, загруженность сервера, кэширование, дизайн страницы и т.д. Очевидно, что предсказать это время нельзя. Поэтому при выполнении автоматизированного браузерного тестирования в Selenium необходимо измерять время загрузки страницы.
Переиспользование запущенного браузера
Зачастую Selenium используется вместе с другими фреймворками для автоматизации тестирования. Некоторые из них имеют аннотации, которые могут использоваться для увеличения скорости выполнения тестов и сокращения времени их разработки.
С помощью аннотаций можно выполнять тесты с различными входными данными. Если использовать правильный набор аннотаций в соответствии с требованиями теста, то это увеличит скорость выполнения тестов Selenium.
Существуют сценарии, когда в одной и той же операционной системе и браузере выполняется группа тестов или один тест. В таких сценариях, выбрав нужный уровень аннотации, можно в самом начале создать новый экземпляр Selenium Webdriver и переиспользовать его во всех тестах данной аннотации.
Фреймворк автоматизации тестирования | Аннотации |
---|---|
JUnit [Selenium Java] | @BeforeClass, @Before, @Test, @After, @AfterClass, @Ignore |
TestNG [Selenium Java] | @BeforeSuite, @BeforeTest, @BeforeClass, @BeforeMethod, @Test, @AfterMethod, @AfterClass, @AfterTest |
NUnit [Selenium C#] | [SetUp], [TearDown], [Test], [TestCase], [OneTimeSetUp], [OneTimeTearDown], [Ignore], [Category] |
XUnit [Selenium C#] | [Theory], [InlineData], [Fact] |
Использование явного ожидания
В Selenium для всех веб-элементов в тестовом сценарии применяется неявное ожидание. При таких условиях, как “Элемент можно выделить”, “Элемент виден”, “Элемент кликабелен” и т.д., вы не можете выполнить ожидание. А вот при явном ожидании можно выполнить условное ожидание для веб-элементов, которые присутствуют на странице.
Если при явном ожидании вы, например, указали, что веб-элемент является “видимым”, то для “невидимого” элемента будет выброшено исключение ElementNotInteractableException. Метод elementToBeClickable
вернет WebElement, если элемент, который был найден, является кликабельным.
Для выполнения операции явного ожидания над веб-элементами используется комбинация классов ExpectedConditions
и WebDriverWait
. Явное ожидание не будет выполняться на удаленном Selenium, а будет выполняться в коде скрипта. Как только заданное условие будет выполнено, явное ожидание выполнит выход из цикла, вместо того чтобы ждать завершения времени. В результате выполнения условия будет возвращен найденный WebElement. В том случае, когда указанное в условии время истекло, а веб-элемента в DOM нет, возникает исключение TimeoutException.
На скриншоте ниже явно указано ожидание в 5 секунд, которое выполняется по условию visibilityOfElementLocated
. Таким образом, если у вас есть веб-элемент, имеющий ID=’element’
, и он обнаруживается в эти 5 секунд, то явное ожидание завершится и будет возвращен требуемый веб-элемент.
Явное ожидание обеспечивает более высокую производительность тестового сценария, поскольку, как только элемент найден, WebElement становится доступным для действий над ним. С помощью явных ожиданий можно ускорить тесты Selenium, поскольку такое ожидание не выполняется в течение всего заданного времени.
Использование параметризации
Бывают случаи, когда требуется запустить тестовый сценарий в различных браузерах и операционных системах, а также при различных комбинациях входных данных. Не стоит писать все значения прямо в коде тестовых методов (хардкодить). Вместо этого при выполнении теста на большом наборе данных можно использовать параметризацию.
В Selenium параметризация не только увеличивает покрытие тестов, но и ускоряет их выполнение. Параметризованные тесты поддерживаются всеми основными фреймворками автоматизации, включая MSTest, NUnit и другие для Selenium C#, JUnit, TestNG и другие для Selenium Java и PyTest для Selenium Python.
Группировка тестовых сценариев
При добавлении в тестовый набор большего количества файлов и тестовых методов сложность его значительно возрастает. Чтобы минимизировать трудности, связанные с реализацией и сопровождением тестового набора, следует группировать тесты в соответствии с тестируемой функциональностью.
Ниже показан пример группировки тест-кейсов в TestNG, где объединяются (по имени) тесты для функции поиска (Search), а распараллеливание выполняется на уровне ‘methods’
.
С помощью атрибута thread-count
задается максимальное количество потоков, создаваемых при запуске тестов. Благодаря нескольким потокам TestNG позволяет осуществлять параллельное выполнение тестовых методов. Группировка тестовых сценариев снижает сложность сопровождения тестовых наборов и позволяет сократить время их выполнения (в зависимости от выбранного подхода к распараллеливанию).
Отключение изображений на странице
Для открытия проверяемой страницы после создания экземпляра веб-драйвера Selenium необходимо использовать метод driver.get()
. Содержимое страницы является одним из основных факторов, влияющих на ее загрузку. Наличие на странице нескольких изображений может увеличить время ее загрузки.
Именно для решения этой проблемы и был добавлен метод отключения загрузки изображений. Ниже приведены примеры отключения загрузки изображений в браузерах Chrome и Firefox.
Отключение загрузки изображений в Chrome
Если вы хотите уменьшить время загрузки страницы на сайте Amazon, можно отключить функцию загрузки изображений в скрипте. Фрагмент скрипта, реализующего эту функцию:
Отключение загрузки изображений в Firefox
Для отключения загрузки изображений в Firefox необходимо установить в настройках браузера для параметра permissions.default.image
значение 2:
Заключение
Когда речь идет о Selenium, вам не нужно беспокоиться о фреймворках и языках, поскольку Selenium сделает это за вас. Он поддерживает различные операционные системы и несколько браузеров. Все, о чем вам нужно позаботиться – это скорость работы, применив вышеуказанные советы. Спасибо за внимание. Успешного обучения!
Перевод статьи «Great Tips on How to Speed up Selenium Automated Tests in 2023».