Советы по суперзаряженному тестированию на 2019 год: руководство по автоматическому тестированию Java

Опубликовано: 2022-03-11

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

В этой статье мы рассмотрим, как вы можете обновить свой фреймворк на 2019 год и как подготовиться к 2020 году. Чтобы улучшить свой фреймворк, я всегда концентрируюсь на «болевых точках». Это области, которые сложны в настройке или вызывают наибольшее количество сбоев. Я определил три основные области, которые хотел упростить или улучшить:

  1. Селеновая сетка
  2. Ждет
  3. Инструменты разработчика Chrome

Selenium Grid, как известно, сложна в настройке и может выйти из строя без предупреждения. Я хотел посмотреть, что, если что, здесь улучшилось. Я также хотел выяснить, были ли добавлены какие-либо новые waits в Selenium API для повышения стабильности любых тестов, которые я создал. Наконец, я хотел посмотреть, смогу ли я начать взаимодействовать с Chrome DevTools через Selenium, которые стали неотъемлемой частью набора инструментов любого тестировщика.

Совет № 1: Dockerize Selenium Grid

Известно, что Selenium Grid сложно настроить, он нестабилен и сложен в развертывании или управлении версиями в конвейере CI. Гораздо более простой, стабильный и удобный способ — использовать готовые образы Selenium Docker.

Примечание. Единственным недостатком этого метода является то, что IE (Internet Explorer) не поддерживается, так как контейнеризация операционной системы Windows пока невозможна.

Подготовка

Чтобы приступить к работе, сначала на вашем компьютере должны быть установлены Docker и Docker Compose. Если вы используете Windows 10 или Mac, они оба будут установлены через рабочий стол Docker.

Запуск вашей сетки

Официальный репозиторий Selenium на Docker Hub содержит готовые образы Docker для вашего Selenium Hub и узлов Firefox и Chrome.

Самый простой способ использовать их в локальной Selenium Grid — создать файл Docker Compose в корневом каталоге вашего проекта. Для простоты назовите файл docker-compose.yml .

Я включил пример ниже, который создает следующую сетку:

  • Единый Selenium Hub
  • Один узел Chrome
  • Один узел Firefox
 #docker-compose.yml version: "3" services: selenium-hub: image: selenium/hub:3.141.59-neon container_name: selenium-hub ports: - "4444:4444" chrome: image: selenium/node-chrome:3.141.59-neon volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444 firefox: image: selenium/node-firefox:3.141.59-neon volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444

Файл Docker Compose описывает настройку вашей сетки. Дополнительные сведения о создании файлов Docker Compose см. в официальной документации.

Чтобы запустить Grid, просто используйте любое окно терминала (окно powershell или cmd в Windows), чтобы запустить следующую команду из корневого каталога вашего проекта:

 docker-compose up

Подключение к сети

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

 // Driver.java protected static RemoteWebDriver browser; DesiredCapabilities cap = new DesiredCapabilities(); ChromeOptions chromeOptions = new ChromeOptions(); cap.setCapability(ChromeOptions.CAPABILITY, chromeOptions); cap.setBrowserName("chrome"); driver = new RemoteWebDriver(cap);

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

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

Дополнительные советы и рекомендации

Если вы хотите видеть, что происходит в браузере, чтобы отлаживать свои тесты, стоит иметь debug версию вашего файла docker-compose.yml , которая загружает узлы debug браузера. Они содержат сервер VNC, поэтому вы можете наблюдать за браузером во время выполнения теста.

Также можно запускать браузеры без головы для увеличения скорости (обычным способом), а Selenium также предоставляет base версии изображений, поэтому вы можете создавать свои собственные изображения, если вам нужно установить дополнительное программное обеспечение.

Чтобы создать стабильную версию Grid для конвейера непрерывной интеграции, также можно развернуть Grid в Kubernetes или Swarm. Это гарантирует, что любые докеры будут быстро восстановлены или заменены в случае их сбоя.

Совет № 2: Умное ожидание

Как известно любому инженеру по автоматизации тестирования, waits имеет решающее значение для стабильности вашей среды автоматизации тестирования. Они также могут ускорить ваш тест, сделав любые sleeps или pauses излишними, и решить проблемы с медленной сетью и кросс-браузером. Ниже приведены несколько советов, которые сделают ваше waits еще более устойчивым.

Учебное пособие по автоматическому тестированию Java № 2. Логические операторы в ожиданиях: будьте конкретны в своих ожиданиях

Класс ExpectedConditions со временем расширился и теперь охватывает почти все мыслимые ситуации. Хотя ExpectedConditions.presenceOfElementLocated(locator) часто бывает достаточно, рекомендуется использовать методы в классе ExpectedCondition , чтобы охватить каждое действие пользователя, внедрив их в класс Actions.java . Это защитит ваши тесты от большинства кросс-браузерных или медленных проблем с веб-сайтом.

Например , если щелчок по ссылке приводит к открытию новой вкладки, используйте ExpectedConditions.numberOfWindowsToBe(2) . Это гарантирует наличие вкладки перед попыткой переключиться на нее.

Вы также можете использовать wait , чтобы гарантировать захват всех элементов, присутствующих на странице, при использовании findElements . Это может быть особенно полезно, если странице search требуется время для возврата результатов. Например, эта строка:

 List<WebElement> results = driver.findElements(locators.RESULTS);

Это может привести к пустому массиву List , если ваши результаты поиска еще не загружены. Вместо этого лучше использовать ожидаемое условие numberOfElementsToBeMoreThan , чтобы дождаться, когда результаты будут больше нуля. Например:

 WebElement searchButton = driver.findElement(locators.SEARCH_BUTTON); searchButton.click(); new WebDriverWait(driver, 30) .until(ExpectedConditions .numberOfElementsToBeMoreThan(locators.RESULTS, 0)); List<WebElement> results = driver.findElements(locators.RESULTS); results.get(0).click();

Теперь ваша команда findElements будет выполняться только после того, как будут возвращены результаты поиска.

Это wait также полезно для поиска одного элемента, когда вы имеете дело с внешним интерфейсом, который плохо работает с Selenium (например, веб-сайты Angular). Создание такого метода защитит ваши тесты, сделав их более стабильными.

 protected static WebElement waitForElement(By locator){ try { new WebDriverWait(browser, 30) .until(ExpectedConditions .numberOfElementsToBeMoreThan(locator, 0)); } catch (TimeoutException e){ e.printStackTrace(); Assert.fail("Timeout: The element couldn't be found in " + WAIT + " seconds!"); } catch (Exception e){ e.printStackTrace(); Assert.fail("Something went wrong!"); } return browser.findElement(locator); }

Можно даже дождаться, пока элементы перестанут быть видимыми. Это особенно полезно, если вы ждете, пока всплывающее окно исчезнет после того, как вы нажали кнопку « OK » или « Save », прежде чем продолжить тест.

 WebElement okButton = driver.findElement(locators.OK_BUTTON); okButton.click(); new WebDriverWait(driver, 30) .until( ExpectedConditions .invisibilityOfElementLocated(locators.POPUP_TITLE) );

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

Учебное пособие по автоматическому тестированию Java № 2: Логические операторы в ожиданиях

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

 wait.until(ExpectedConditions.and( ExpectedConditions.presenceOfElementLocated(locator), ExpectedConditions.elementToBeClickable(locator) ) );

Оператор ИЛИ был бы уместен, если бы вы не были уверены, может ли измениться заголовок страницы. Затем вы можете включить проверку URL-адреса, если первое условие не выполняется, чтобы подтвердить, что вы определенно находитесь на нужной странице.

 wait.until(ExpectedConditions.or( ExpectedConditions.titleIs(expectedTitle), ExpectedConditions.urlToBe(expectedUrl) ) );

Или, если вы хотите убедиться, что флажок больше не активен после выполнения действия на странице, тогда подходит оператор NOT.

 wait.until(ExpectedConditions.not( ExpectedConditions.elementToBeClickable(locator) ) );

Использование операторов может сделать ваши waits более устойчивыми и привести к менее хрупким тестам.

Совет № 3. Chrome DevTools: моделирование сетевых условий

Запуск вашего веб-приложения на локальном хосте или в локальной сети может создать ложное впечатление о его производительности при работе в дикой природе. Возможность регулировать различные скорости загрузки и выгрузки даст вам лучшее представление о том, как ваше приложение будет работать в Интернете, где тайм-ауты могут привести к сбою действий. Мы можем начать симулировать это, используя возможности Chrome DevTools.

Следующий код откроет домашнюю страницу Toptal с разной скоростью загрузки и выгрузки. Во-первых, мы сохраним наши скорости в поставщике данных TestNG, используя следующий код:

 import org.testng.annotations.DataProvider; public class ExcelDataProvider { @DataProvider(name = "networkConditions") public static Object[][] networkConditions() throws Exception { return new Object[][] { // Upload Speed, Dowload Speed in kb/s and latency in ms. { 5000 , 5000, 5 }, { 10000, 7000, 5 }, { 15000, 9000, 5 }, { 20000, 10000, 5 }, { 0, 0 }, }; } }

Примечание. Регулирование загрузки и выгрузки измеряется в kb/s , а задержка — в ms .

Затем мы можем использовать эти данные для запуска нашего теста в различных сетевых условиях. В рамках теста CommandExecutor выполнит команду в текущем сеансе браузера. Это, в свою очередь, активирует необходимые настройки в инструментах разработчика Chrome для имитации нашей медленной сети. Код внутри оператора if может быть включен в метод @BeforeClass при выполнении набора тестов.

 import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.openqa.selenium.remote.Command; import org.openqa.selenium.remote.CommandExecutor; import org.openqa.selenium.remote.Response; public class TestClass { // load our data provider @Test(dataProvider = "networkConditions") public void test(int download, int upload, int latency) throws IOException { // only run if the network is throttled if (download > 0 && upload > 0) { CommandExecutor executor = driver.getCommandExecutor(); // create a hashmap of the required network conditions Map map = new HashMap(); // you can even test 'offline' behaviour map.put("offline", false); map.put("latency", latency); map.put("download_throughput", downloadThroughput); map.put("upload_throughput", uploadThroughput); // execute our code Response response = executor.execute( new Command(driver.getSessionId(), "setNetworkConditions", ImmutableMap.of("network_conditions", ImmutableMap.copyOf(map)))); } // Open the website driver.get("https://www.toptal.com/"); // You can then check that elements are loaded etc. // Don't forget to use waits! } }
Связанный: Build with Confidence: Руководство по тестам JUnit

Дополнительный совет: как управлять файлами cookie

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

Приведенный ниже код позволяет удалить все ваши файлы cookie:

 driver.manage().deleteAllCookies();

Вы также можете удалить файл cookie по имени:

 driver.manage().deleteCookieNamed("CookieName");

Или получить содержимое файла cookie:

 String myCookie = driver.manage().getCookieNamed("CookieName").getValue();

Или получить все куки:

 List<Cookie> cookies = driver.manage().getCookies();

Автоматизация тестирования в 2020 году: взгляд в будущее

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

Примечание. Вы можете отслеживать их прогресс, просматривая дорожную карту.

Стандартизация веб-драйвера W3C

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

Простая селеновая сетка

Selenium Grid будет более стабильным и простым в настройке и управлении в Selenium 4. Пользователям больше не нужно будет настраивать и запускать концентраторы и узлы по отдельности, поскольку сетка будет действовать как объединенный узел и концентратор. Кроме того, будет улучшена поддержка Docker, параллельное тестирование будет включено изначально, а пользовательский интерфейс станет более информативным. Трассировка запросов с помощью хуков также поможет вам отлаживать сетку.

Документация

Документация Selenium подвергнется столь необходимой переработке, поскольку она не обновлялась с момента выпуска Selenium 2.0.

Изменения в API

Поддержка браузеров Opera и PhantomJS будет удалена. Безголовый запуск можно выполнять с Chrome или Firefox, а Opera построена на Chromium, поэтому тестирование Chromium считается достаточным для этого браузера.

WebElement.getSize() и WebElement.getLocation() теперь заменены одним методом WebElement.getRect() . Однако, поскольку они часто используются для создания снимков экрана одного элемента, стоит знать, что в Selenium 4 также будет команда API для захвата снимка экрана элемента.

Для WebDriver Window методы getPosition и getSize будут заменены методом getRect , а методы setPosition и setSize будут заменены методом setRect . будут доступны методы fullscreen и minimize , поэтому эти действия можно выполнять в рамках теста.

Другие заметные изменения:

  • Класс Options для каждого браузера теперь будет расширять класс Capabilities .
  • Добавлен driver.switchTo().parentFrame() , упрощающий навигацию по кадрам.
  • будут включены nice локаторы, которые работают на более высоком уровне по сравнению с текущими. Они будут подклассом By .
  • Будет реализован API DevTools , позволяющий пользователям использовать преимущества функций, предлагаемых с помощью протокола отладки Chrome (и его эквивалентов в других браузерах). Это включает:
    • Полные скриншоты страницы (включая закадровые элементы).
    • Журналы потоковой передачи.
    • Ожидание событий мутации на странице.
  • Многие устаревшие методы и классы также будут удалены.

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

Заключение

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

Внесение изменений, которые я обрисовал в общих чертах выше, является хорошим началом, однако я настоятельно рекомендую вам просмотреть всю вашу структуру на предмет «болевых точек», поскольку вы можете внести улучшения, которые я не рассмотрел. Например, используете ли вы WebDriver Manager для управления драйверами или все еще обновляете их вручную?

Я бы также рекомендовал установить дату, чтобы делать это не реже одного раза в год, хотя в идеале это должно быть каждые шесть месяцев. В статью я включил изменения, которые появятся в Selenium 4.0. Пожалуйста, просмотрите alpha -версии Selenium для себя. Изменения будут кардинальными, и вам нужно быть готовым. Я надеюсь, что вы нашли это полезным. Если вы обнаружите какие-либо новые методы или приемы во время генеральной уборки вашего фреймворка, поделитесь ими с другими читателями этого блога, добавив их в раздел комментариев ниже.

Кроме того, если вы хотите взглянуть на автоматизированные тесты в Selenium и на то, как вы можете использовать модели Page Object для написания поддерживаемых и повторно используемых процедур тестирования, ознакомьтесь с Automation in Selenium: Page Object Model и Page Factory .

Связанный: Язык Dart: когда Java и C # недостаточно четкие