Введение в проблему
Большую часть времени, когда вам нужно писать функциональные тесты / сквозные тесты для веб-интерфейса, вы в конечном итоге используете Selenium , который он может рассматривать в качестве фактического инструмента в мире Java для тестирования веб-интерфейса. Я уверен, что вы уже использовали его для такого рода тестов.
Но, вероятно, в то же время вы столкнулись с некоторыми наиболее распространенными проблемами в функциональном тестировании, некоторые из которых связаны с тестированием веб-интерфейса, а другие нет.
Например, одна из основных проблем, которые обычно встречаются в функциональных тестах, — это подготовка среды, для запуска тестов вам нужно загрузить сервер и развернуть приложение, затем установить / запустить базу данных, а также, возможно, систему кеша и т. Д. со всеми серверами, оставляя пользователю возможность локальной установки каждого сервиса. Могут возникнуть некоторые ошибки, например, установка неверной версии сервера, используемой в производственной среде, повторное использование другой локальной установки базы данных, которая может отличаться от версии, или, например, запуск их в другой версии JDK, отличной от той, которая используется в производственной среде.
Но также есть и другие проблемы, которые более специфичны для тестирования веб-интерфейса, такие как установка браузера или настройка свойств WebDriver.
Исправление первой проблемы
Чтобы решить первую проблему, самое простое решение, которое вы можете себе представить, — это использование контейнеров Docker и, конечно, создание Docker, поскольку вы можете определять и запускать мультиконтейнерные приложения Docker. Таким образом, в основном вы определяете в файле docker-compose все серверы, которые могут вам понадобиться для запуска тестов, поэтому при запуске тестов у вас все они работают и, что более важно, с фиксированной версией, поэтому вы можете быть уверены, что тесты всегда работать с известной / желаемой конкретной версией серверов, тем же JDK,… и не в зависимости от того, что установлено в машине разработчиков / CI.
Но у этого подхода есть одна проблема. Вам нужно специально запустить docker-compose up , docker-compose down. Конечно, вы можете автоматизировать это в своем скрипте сборки, который решит проблему в среде CI, но если разработчик хочет выполнить тест из IDE, скажем, для отладки, то он должен знать об этом факте.
И это то, что решает Arquillian Cube . Arquillian Cube — это расширение Arquillian, использующее файл docker-compose для запуска и настройки всех определенных в нем контейнеров, выполнения тестов и, наконец, закрытия всех из них. Хорошей новостью является то, что, поскольку Arquillian работает с JUnit (и TestNG и Spock), вы можете запускать тесты из IDE, не беспокоясь о запуске и остановке контейнеров, поскольку жизненным циклом Docker управляет Arquillian Cube.
Итак, первая часть проблемы, которая определяет среду тестирования, исправлена с помощью Arquillian Cube. Давайте посмотрим, как исправить второй.
Исправление второй проблемы
Проект Selenium предоставляет образы Docker с автономным Selenium или узлом Selenium с браузером (Firefox или Chrome) и установленным сервером VNC.
Таким образом, кажется, что он идеально подходит для решения проблемы необходимости устанавливать браузеры с конкретной версией или конкретными конфигурациями локально, поскольку вы можете использовать образ докера с браузером, настроенным для тестов.
Новые проблемы при использовании Docker для тестирования
И это круто, но у него есть некоторые проблемы. Во-первых, вам нужно создать файл docker-compose, специфичный для целей тестирования, хотя это само по себе неплохо, но для поддержки этого файла требуется больше управления со стороны dev и, конечно, повторять снова и снова. во всех проектах, которые вы хотите использовать, определяя используемый браузер и образ клиента VNC, чтобы получить запись для будущего осмотра.
Вторая проблема — это конфигурация WebDriver. При запуске WebDriver с удаленным браузером вам необходимо установить местоположение (IP) браузера и настроить RemoteWebDriver в соответствии с желаемыми возможностями.
Поэтому вам снова и снова приходится писать во всех тестах конфигурацию WebDriver. Вы можете создать фабричный класс, который можно повторно использовать во всех проектах, и это хорошо, но у вас все еще есть одна проблема: некоторые разработчики могут использовать машину Docker, поэтому IP-адрес не будет статичным и может меняться каждый раз, другие могут использовать собственный Docker, и, например, некоторые фазы конвейера CI могут запускать тесты в удаленной полностью среде, такой как среда подготовки, поэтому перед выполнением тестов вам потребуется вручную указать IP-адрес контейнера хоста Docker.
И третья проблема, с которой вы столкнетесь, заключается в том, что вам нужно дать WebDriver команду открыть страницу: webdriver.get («http://www.google.com»);
Проблема в том, что в этом случае браузер находится внутри инфраструктуры Docker, поэтому вам нужно установить внутренний IP-адрес контейнера сервера, поэтому вам нужно знать не только IP-адрес хоста Docker для подключения к удаленному веб-драйверу, но и внутренний IP-адрес контейнера сервера для открытия страницы в удаленном браузере с помощью
получить метод. И снова это может быть довольно трудно приобрести автоматически.
Но все эти проблемы решаются при использовании новой интеграции между Arquillian Drone и Arquillian Cube.
Исправление новых проблем
Arquillian Drone — это расширение Arquillian, которое интегрирует Selenium WebDriver в Arquillian. Это расширение управляет конфигурацией WebDriver, поэтому вам не нужно повторять его во всех ваших тестах, а также на протяжении всего жизненного цикла браузера.
Итак, как вы можете видеть, эта пара расширений идеально подходит для решения этих проблем. Drone заботится о конфигурации, в то время как Cube заботится о правильной настройке контейнеров Selenium / VNC, их запуске и остановке.
Как вы можете видеть, вам не нужно беспокоиться о создании файла docker-compose для тестирования. Вам нужно только создать тот, который используется для развертывания, а Arquillian позаботится обо всем остальном.
пример
Первое, что нужно сделать, это создать проект с необходимыми зависимостями. В этом примере мы используем Maven, но вы можете добиться того же, используя другие инструменты сборки.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
<? xml version = "1.0" encoding = "UTF-8" ?> < modelVersion >4.0.0</ modelVersion > < groupId >org.lordofthejars.helloworld</ groupId > < artifactId >dronecube</ artifactId > < version >1.0-SNAPSHOT</ version > < dependencyManagement > < dependencies > <!-- Use BOMs to set same versions in all dependencies --> < dependency > < groupId >org.jboss.arquillian</ groupId > < artifactId >arquillian-bom</ artifactId > < version >1.1.11.Final</ version > < type >pom</ type > < scope >import</ scope > </ dependency > < dependency > < groupId >org.jboss.arquillian.extension</ groupId > < artifactId >arquillian-drone-bom</ artifactId > < version >2.0.0.Final</ version > < type >pom</ type > < scope >import</ scope > </ dependency > < dependency > < groupId >org.jboss.arquillian.selenium</ groupId > < artifactId >selenium-bom</ artifactId > < version >2.53.1</ version > < type >pom</ type > < scope >import</ scope > </ dependency > </ dependencies > </ dependencyManagement > < dependencies > <!-- Use standalone mode in Arquillian (no @Deployment) --> < dependency > < groupId >org.jboss.arquillian.junit</ groupId > < artifactId >arquillian-junit-standalone</ artifactId > < scope >test</ scope > </ dependency > <!-- Cube dependencies --> < dependency > < groupId >org.arquillian.cube</ groupId > < artifactId >arquillian-cube-docker</ artifactId > < version >1.0.0.Alpha13</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >org.arquillian.cube</ groupId > < artifactId >arquillian-cube-docker-drone</ artifactId > < version >1.0.0.Alpha13</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >org.assertj</ groupId > < artifactId >assertj-core</ artifactId > < version >3.5.2</ version > < scope >test</ scope > </ dependency > < dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < version >4.12</ version > < scope >test</ scope > </ dependency > <!-- Drone dependencies --> < dependency > < groupId >org.jboss.arquillian.extension</ groupId > < artifactId >arquillian-drone-webdriver-depchain</ artifactId > < type >pom</ type > < scope >test</ scope > </ dependency > </ dependencies > </ project > |
Важно отметить, что вы используете определения спецификации для установки версий компонентов. Затем мы устанавливаем зависимость Arquillian Standalone, потому что наш тест не будет иметь
Метод @Deployment, поскольку файл развертывания уже создан внутри образа Docker, используемого в приложении. Наконец, добавлены зависимости Arquillian Cube и Arquillian Drone.
Следующим шагом является создание в src / test / resources файла arquillian.xml, который используется для настройки расширений.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
<? xml version = "1.0" ?> xsi:schemaLocation="http://jboss.org/schema/arquillian < extension qualifier = "docker" > <!-- Not required if native docker or only one docker machine installed --> < property name = "machineName" >dev</ property > <!-- Not required if file is in root of classpath --> < property name = "dockerContainersFile" >docker-compose.yml</ property > </ extension > </ arquillian > |
Ты это видишь:
- Вам необходимо указать имя док-машины, где запускать контейнеры в случае использования док-машины. Если вы используете собственный Docker, вам не нужно устанавливать этот атрибут.
- Вам необходимо указать местоположение относительно корневой папки проекта, в которой находится файл docker-compose . Обратите внимание, что вы можете использовать любое другое имя.
Вы можете настроить WebDriver, а также настроить Arquillian Drone ( https://docs.jboss.org/author/display/ARQ/Drone ), но для этого теста достаточно значений по умолчанию. Обратите внимание, что теперь браузером по умолчанию является Firefox .
ВАЖНО : если вы используете встроенную установку Linux Docker, прокомментируйте строку конфигурации machineName . Если вы используете докер и он называется dev , то адаптируйте
machineName в arquillian.xml тоже.
Следующим шагом является создание файла docker-compose в корневом каталоге.
1
2
3
4
|
helloworld: image: lordofthejars/helloworldgo ports: - "8080:80" |
Простой составной файл, который определяет только один контейнер. Этот контейнер предоставляет порт 80, но затем он привязывается к порту 8080. Этот контейнер запускает программу Go, слушающую корневой контекст и возвращающую
Привет, мир в формате HTML.
И наконец тест:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package org.lordofthejars.cubedrone; import org.arquillian.cube.CubeIp; import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.junit.Arquillian; import org.junit.Test; import org.junit.runner.RunWith; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import java.net.MalformedURLException; import java.net.URL; import static org.assertj.core.api.Assertions.assertThat; @RunWith (Arquillian. class ) public class HelloWorldTest { public static final int EXPOSED_PORT = 80 ; // Enrich with webdriver configured to connect to remote browser @Drone WebDriver webDriver; // Enrich with helloworld container ip @CubeIp (containerName = "helloworld" ) String ip; @Test public void shouldShowHelloWorld() throws MalformedURLException, InterruptedException { // Constructs url that browser should connect URL url = new URL( "http" , ip, EXPOSED_PORT, "/" ); // Typical test using WebDriver webDriver.get(url.toString()); final String message = webDriver.findElement(By.tagName( "h1" )).getText(); assertThat(message).isEqualTo( "Hello World" ); } } |
В этом тесте есть несколько интересных частей.
- Это стандартный тест Arquillian в том смысле, что он использует бегун Arquillian.
- Использует механизм внедрения @Drone, предоставленный Arquillian Drone, для обогащения теста с помощью WebDriver, настроенного для подключения к удаленному браузеру.
- Использует аннотацию @CubeIp для обогащения теста внутренним IP- адресом контейнера helloworld . Поскольку браузер работает внутри хоста Docker, для этой цели мы можем использовать внутренний IP-адрес. Также важно, что вам нужно использовать открытый порт, а не порт привязки.
- Все остальное управляется Arquillian Cube, как запуск и остановка контейнеров Docker (в данном случае helloworld ), но также и те, которые содержат браузер и клиент VNC. Если вы поместите точку отладки в метод теста, а затем запустите docker ps на терминале, вы увидите, что запущены три контейнера, а не просто helloworld .
- Если после запуска теста вы осмотрите каталог target / reports / videos, вы найдете видеозапись теста.
Вы также можете увидеть скриншот этого в действии:
Так что, как вы можете видеть, использование Arquillian Cube с Arquillian Drone делает ваш тестовый и докерный файл выглядит действительно аккуратно. Тест содержит только то, что связано с тестом, а не о конфигурации WebDriver. Кроме того, ваш docker-compose выглядит ясно, он содержит только вещи, связанные с бизнесом, а не с тестированием.
В этом посте вы увидели, как использовать Arquillian Cube + Arquillian Drone. В следующем вы увидите интеграцию с Arquillian Graphene, которая еще больше упростит тестирование, сосредоточившись только на тестировании, а не на вызовах WebDriver.
Ссылка: | Сделайте тестирование веб-интерфейса снова великолепным с Arquillian, Docker и Selenium (часть 1) от нашего партнера JCG Алекса Сото в блоге One Jar To Rule All . |