Użycie Docker Selenium w pipeline
Spis treści
Powrót do przeszłości
W poprzedniej lekcji dowiedziałeś się jak może wyglądać przykładowy pipeline w Jenkinsie. Jest to jedna z najprostszych możliwych implementacji. Czas na jego rozbudowę.
Aktualnie pipeline wygląda następująco:
pipeline {
agent any
stages {
stage('Build test code') {
steps {
sh 'mvn clean install -DskipTests'
}
}
stage('Execute test') {
steps {
sh 'mvn test'
}
}
stage('Generate allure report') {
steps {
script {
allure([
includeProperties: false,
jdk : '',
properties : [],
reportBuildPolicy: 'ALWAYS',
results : [[path: 'target/allure-results']]
])
}
}
}
}
}
Analizując pipeline oraz framework, który go obsługuje widzimy, że ma on pewne wady. Do których należą:
- Testy możemy uruchomić tylko w sposób taki jak zostało to przewidziane w kodzie. Konfiguracja jest zahardkodowana,
- Do poprawnego uruchomienia i wykonania testów potrzebujemy zewnętrznego Selenium GRIDa,
- Framework, który go obsługuje wymaga zewnętrznego Selenium GRID lub uruchomienia go w trybie lokalny driverów. Tryb lokalnych driverów powinien służyć tylko i wyłącznie do lokalnego developmentu testów, nie zaś do uruchamiania ich w ramach ciągłej integracji.
- Raport Allure nie zostanie wygenerowany, jeśli stage „Execute test" nie zostanie wykonany.
Te i wiele innych problemów możemy wymieniać w nieskończoność. Czas zabrać się za jeden z nich jakim jest brak Selenium GRIDa w ramach pipelinu.
Problem zewnętrznego Selenium GRIDa.
Dla bieżącej implementacji uruchomienie testów na Selenium GRID wymaga infrastruktury jak na obrazku poniżej:
Jest to klasyczne podejście w którym mamy:
- Jenkins -- Serwer CI (Continues Integration) -- który jest osobną maszyną odpowiadającą za hostowanie Jenkinsa tzw. Jenkins Master,
- Jenkins Agent -- maszyna na której uruchamiany jest kod testów tzw. Jenkins Slave,
- Selenium Hub -- maszyna z zainstalowanym Selenium Hub
- Selenium Node -- kolejne maszyny z odpowiednimi przeglądarkami i Selenium GRID w trybie Node.
Takie klasyczne podejście ma szereg problemów, do których możemy zaliczyć:
- Wiele elementów infrastruktury, które potencjalnie mogą zawieść,
- Brak kontroli nad infrastrukturą,
- Ograniczone zasoby,
- Duży koszt (duża liczba maszyn).
Rozwiązaniem części z powyższych problemów jest Docker Selenium.
Dzięki zastosowaniu dokeryzacji Selenium GRIDa przenosimy wykonanie testów, oraz infrastrukturę Selenium GRIDa z zewnętrznej maszyny, nad którą nie mamy kontroli na agenta Jenkinsowego.
Przejdźmy w takim razie do implementacji.
Docker Selenium
Zanim zaczniemy, mała dygresja. Jeśli nie wiesz czym jest Docker Selenium w ramach kursu dostępny jest artykuł wprowadzający w zagadnienie. Możesz też zapoznać się z dokumentacją twórców.
Czas na jego przykładowe zastosowanie. W naszym przykładzie użyjemy najprostszego możliwego docker-compose.yml, który będzie agregował nam Selenium Hub oraz dwa nody z przeglądarkami Chrome oraz Firefox.
I tak mamy docker-compose.yml:
version: "3"
services:
selenium-hub:
image: selenium/hub:3.141.59-yttrium
container_name: selenium-hub
ports:
- "4444:4444"
chrome:
image: selenium/node-chrome:3.141.59-yttrium
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-yttrium
volumes:
- /dev/shm:/dev/shm
depends_on:
- selenium-hub
environment:
- HUB_HOST=selenium-hub
- HUB_PORT=4444
Plik docker-compose.yml umieszczamy w głównym katalogu repozytorium.
Kolejnym krokiem będzie zmiana w ramach pliku configuration.propertiesna następujące wartości:
is.remote.run=true
grid.url=http://localhost:4444/wd/hub
Wartość localhostbieżę się stąd, że Selenium GRID będzie się znajdować na tej samej maszynie co testy, w ramach kontenera dockerowego.
Mając gotowy docker-compose.yml możemy przejść do modyfikacji Jenkinsfile . Dzieki zastosowaniu podejścia infrastructure as a code wszystko znajduję się w repozytorium. Nie musimy modyfikować pipelinu utworzonego w ramach lekcji.
Dla przypomnienia aby uruchomić kontenery zdefiniowane w docker-compose.yml wywołujemy komendę:
docker-compose up -d
W celu ich wyłączenia kontenerów:
docker-compose down
Przechodząc do implementacji Jenkinsfilemamy:
pipeline {
agent any
stages {
stage('Build test code') {
steps {
sh 'mvn clean install -DskipTests' // Budowanie testów
}
}
stage('Run selenium grid') {
steps {
sh 'docker-compose up -d' // Uruchiomienie Docker Selenium
}
}
stage('Execute test') {
steps {
sh 'mvn test' // Uruchomienie testów
sh 'docker-compose down' // Wyłączenie Docker Selenium, wyłączenie kontenerów
}
}
}
post {
always {
script { // Wygenerowanie raportu Allurowego
allure([
includeProperties: false,
jdk : '',
properties : [],
reportBuildPolicy: 'ALWAYS',
results : [[path: 'target/allure-results']]
])
}
}
}
}
Dodatkowo w porównaniu do poprzedniego pipelina, przenieśliśmy skrypt odpowiadający za generowanie raportu Allurowego do sekcji post . Sekcja post jest to sekcja, która wykona się zawsze po przejściu całego planu, niezależnie od wyniku.
Uwaga: Do poprawnego uruchomienia powyższego pipelinu na maszynie agenta powinien być zainstalowany docker!
Jeśli teraz uruchomimy zmodyfikowany pipeline, zobaczymy:
[Pipeline] }
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Build test code)
[Pipeline] sh
+ mvn clean install -DskipTests
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< pl.javastart.courses:selenium-intro >-----------------
[INFO] Building selenium-intro 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ selenium-intro ---
[INFO] Deleting D:\Program Files (x86)\Jenkins\workspace\Test\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ selenium-intro ---
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 3 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ selenium-intro ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ selenium-intro ---
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ selenium-intro ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 26 source files to D:\Program Files (x86)\Jenkins\workspace\Test\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ selenium-intro ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ selenium-intro ---
[INFO] Building jar: D:\Program Files (x86)\Jenkins\workspace\Test\target\selenium-intro-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ selenium-intro ---
[INFO] Installing D:\Program Files (x86)\Jenkins\workspace\Test\target\selenium-intro-1.0-SNAPSHOT.jar to C:\Windows\system32\config\systemprofile\.m2\repository\pl\javastart\courses\selenium-intro\1.0-SNAPSHOT\selenium-intro-1.0-SNAPSHOT.jar
[INFO] Installing D:\Program Files (x86)\Jenkins\workspace\Test\pom.xml to C:\Windows\system32\config\systemprofile\.m2\repository\pl\javastart\courses\selenium-intro\1.0-SNAPSHOT\selenium-intro-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.722 s
[INFO] Finished at: 2020-01-12T10:11:24+01:00
[INFO] ------------------------------------------------------------------------
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Run selenium grid)
[Pipeline] sh
+ docker-compose up -d
Creating network "test_default" with the default driver
Pulling selenium-hub (selenium/hub:3.141.59-yttrium)...
3.141.59-yttrium: Pulling from selenium/hub
Digest: sha256:6f6bdd8d5ce5cd8d7be42ded88bc3dbbdf7a60ec32c908eb26dd31b37f69589a
Status: Downloaded newer image for selenium/hub:3.141.59-yttrium
Pulling chrome (selenium/node-chrome:3.141.59-yttrium)...
3.141.59-yttrium: Pulling from selenium/node-chrome
Digest: sha256:5e37ffdeae0864dd7f0df63adafcc9428766d79976a645853bc1e20d7487ff4f
Status: Downloaded newer image for selenium/node-chrome:3.141.59-yttrium
Pulling firefox (selenium/node-firefox:3.141.59-yttrium)...
3.141.59-yttrium: Pulling from selenium/node-firefox
Digest: sha256:3a92810aca49182944c72e15c68dd8561731f25e723983d8702a9234d32163d6
Status: Downloaded newer image for selenium/node-firefox:3.141.59-yttrium
Creating selenium-hub ...
[1A [2K
Creating selenium-hub ... [32mdone [0m
[1BCreating test_firefox_1 ...
Creating test_chrome_1 ...
[2A [2K
Creating test_firefox_1 ... [32mdone [0m
[2B [1A [2K
Creating test_chrome_1 ... [32mdone [0m
[1B
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Execute test)
[Pipeline] sh
+ mvn test
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< pl.javastart.courses:selenium-intro >-----------------
[INFO] Building selenium-intro 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ selenium-intro ---
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 3 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:compile (default-compile) @ selenium-intro ---
[INFO] No sources to compile
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ selenium-intro ---
[WARNING] Using platform encoding (Cp1250 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.7.0:testCompile (default-testCompile) @ selenium-intro ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.21.0:test (default-test) @ selenium-intro ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running TestSuite
[INFO ] 2020-01-12 10:12:34.795 [TestNG-tests-2] configuration.PropertiesLoader - Trying to load properties with file name: configuration.properties
[INFO ] 2020-01-12 10:12:34.795 [TestNG-tests-1] configuration.PropertiesLoader - Trying to load properties with file name: configuration.properties
[INFO ] 2020-01-12 10:12:34.803 [TestNG-tests-2] configuration.PropertiesLoader - Successfully loaded properties for file: configuration.properties
[INFO ] 2020-01-12 10:12:34.803 [TestNG-tests-1] configuration.PropertiesLoader - Successfully loaded properties for file: configuration.properties
sty 12, 2020 10:12:35 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
[INFO ] 2020-01-12 10:12:35.982 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to navigate to http://przyklady.javastart.pl/jpetstore/
[INFO ] 2020-01-12 10:12:36.114 [TestNG-tests-2] driver.listeners.DriverEventListener - Navigated to http://przyklady.javastart.pl/jpetstore/
[INFO ] 2020-01-12 10:12:36.209 [TestNG-tests-2] utils.testng.listeners.TestListener - Starting test: asUserLoginUsingValidLoginAndPassword
[INFO ] 2020-01-12 10:12:36.234 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to navigate to http://przyklady.javastart.pl/jpetstore/actions/Account.action?signonForm=
[INFO ] 2020-01-12 10:12:36.376 [TestNG-tests-2] driver.listeners.DriverEventListener - Navigated to http://przyklady.javastart.pl/jpetstore/actions/Account.action?signonForm=
[INFO ] 2020-01-12 10:12:36.407 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.name: username
[INFO ] 2020-01-12 10:12:36.429 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.name: username
[INFO ] 2020-01-12 10:12:36.484 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.name: username
[INFO ] 2020-01-12 10:12:36.500 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.name: username
[INFO ] 2020-01-12 10:12:36.514 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to type into element: input text [j2ee]
[INFO ] 2020-01-12 10:12:36.586 [TestNG-tests-2] driver.listeners.DriverEventListener - Typed into element: input text [j2ee]
[INFO ] 2020-01-12 10:12:36.588 [TestNG-tests-2] page.objects.LoginPage - Typed into User Name Field j2ee
[INFO ] 2020-01-12 10:12:36.588 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.name: password
[INFO ] 2020-01-12 10:12:36.611 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.name: password
[INFO ] 2020-01-12 10:12:36.621 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to enter empty string or clear element: input
[INFO ] 2020-01-12 10:12:36.663 [TestNG-tests-2] driver.listeners.DriverEventListener - Entered empty string or cleared element: input
[INFO ] 2020-01-12 10:12:36.664 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.name: password
[INFO ] 2020-01-12 10:12:36.681 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.name: password
[INFO ] 2020-01-12 10:12:36.695 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to type into element: input text [j2ee]
[INFO ] 2020-01-12 10:12:36.788 [TestNG-tests-2] driver.listeners.DriverEventListener - Typed into element: input text [j2ee]
[INFO ] 2020-01-12 10:12:36.788 [TestNG-tests-2] page.objects.LoginPage - Typed into Password Field j2ee
[INFO ] 2020-01-12 10:12:36.788 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.name: signon
[INFO ] 2020-01-12 10:12:36.822 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.name: signon
[INFO ] 2020-01-12 10:12:36.838 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to click on element with tag name: input
[INFO ] 2020-01-12 10:12:37.026 [TestNG-tests-2] driver.listeners.DriverEventListener - Clicked on element
[INFO ] 2020-01-12 10:12:37.026 [TestNG-tests-2] page.objects.LoginPage - Clicked on Login Button
[INFO ] 2020-01-12 10:12:37.027 [TestNG-tests-2] page.objects.FooterPage - Checking if dog banner is displayed
[INFO ] 2020-01-12 10:12:37.027 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.cssSelector: #Banner img[src*='dog']
[INFO ] 2020-01-12 10:12:37.052 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.cssSelector: #Banner img[src*='dog']
[INFO ] 2020-01-12 10:12:37.119 [TestNG-tests-2] generic.assertions.AssertWebElement - Checking if element is displayed
[INFO ] 2020-01-12 10:12:37.119 [TestNG-tests-2] driver.listeners.DriverEventListener - Trying to find element with locator By.cssSelector: #Banner img[src*='dog']
[INFO ] 2020-01-12 10:12:37.150 [TestNG-tests-2] driver.listeners.DriverEventListener - Found element with locator By.cssSelector: #Banner img[src*='dog']
[INFO ] 2020-01-12 10:12:37.172 [TestNG-tests-2] generic.assertions.AssertWebElement - WebElement was displayed!
[INFO ] 2020-01-12 10:12:37.174 [TestNG-tests-2] utils.testng.listeners.TestListener - Test asUserLoginUsingValidLoginAndPassword passed successfully
sty 12, 2020 10:12:37 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
[INFO ] 2020-01-12 10:12:37.410 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to navigate to http://przyklady.javastart.pl/jpetstore/
[INFO ] 2020-01-12 10:12:37.557 [TestNG-tests-1] driver.listeners.DriverEventListener - Navigated to http://przyklady.javastart.pl/jpetstore/
[INFO ] 2020-01-12 10:12:37.561 [TestNG-tests-1] utils.testng.listeners.TestListener - Starting test: asUserTryToLogInWithIncorrectLoginAndPassword
[INFO ] 2020-01-12 10:12:37.564 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to navigate to http://przyklady.javastart.pl/jpetstore/actions/Account.action?signonForm=
[INFO ] 2020-01-12 10:12:37.734 [TestNG-tests-1] driver.listeners.DriverEventListener - Navigated to http://przyklady.javastart.pl/jpetstore/actions/Account.action?signonForm=
[INFO ] 2020-01-12 10:12:37.734 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.name: username
[INFO ] 2020-01-12 10:12:37.750 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.name: username
[INFO ] 2020-01-12 10:12:37.780 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.name: username
[INFO ] 2020-01-12 10:12:37.793 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.name: username
[INFO ] 2020-01-12 10:12:37.802 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to type into element: input text [NotExistingLogin]
[INFO ] 2020-01-12 10:12:37.832 [TestNG-tests-1] driver.listeners.DriverEventListener - Typed into element: input text [NotExistingLogin]
[INFO ] 2020-01-12 10:12:37.832 [TestNG-tests-1] page.objects.LoginPage - Typed into User Name Field NotExistingLogin
[INFO ] 2020-01-12 10:12:37.832 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.name: password
[INFO ] 2020-01-12 10:12:37.846 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.name: password
[INFO ] 2020-01-12 10:12:37.853 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to enter empty string or clear element: input
[INFO ] 2020-01-12 10:12:37.885 [TestNG-tests-1] driver.listeners.DriverEventListener - Entered empty string or cleared element: input
[INFO ] 2020-01-12 10:12:37.885 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.name: password
[INFO ] 2020-01-12 10:12:37.897 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.name: password
[INFO ] 2020-01-12 10:12:37.904 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to type into element: input text [NotProperPassword]
[INFO ] 2020-01-12 10:12:37.936 [TestNG-tests-1] driver.listeners.DriverEventListener - Typed into element: input text [NotProperPassword]
[INFO ] 2020-01-12 10:12:37.936 [TestNG-tests-1] page.objects.LoginPage - Typed into Password Field NotProperPassword
[INFO ] 2020-01-12 10:12:37.936 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.name: signon
[INFO ] 2020-01-12 10:12:37.949 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.name: signon
[INFO ] 2020-01-12 10:12:37.955 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to click on element with tag name: input
[INFO ] 2020-01-12 10:12:38.028 [TestNG-tests-1] driver.listeners.DriverEventListener - Clicked on element
[INFO ] 2020-01-12 10:12:38.028 [TestNG-tests-1] page.objects.LoginPage - Clicked on Login Button
[INFO ] 2020-01-12 10:12:38.028 [TestNG-tests-1] page.objects.LoginPage - Checking if warning message Invalid username or password. Signon failed. is displayed
[INFO ] 2020-01-12 10:12:38.029 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.cssSelector: #Content ul[class='messages'] li
[INFO ] 2020-01-12 10:12:38.040 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.cssSelector: #Content ul[class='messages'] li
[INFO ] 2020-01-12 10:12:38.075 [TestNG-tests-1] generic.assertions.AssertWebElement - Checking if element is displayed
[INFO ] 2020-01-12 10:12:38.075 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.cssSelector: #Content ul[class='messages'] li
[INFO ] 2020-01-12 10:12:38.087 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.cssSelector: #Content ul[class='messages'] li
[INFO ] 2020-01-12 10:12:38.110 [TestNG-tests-1] generic.assertions.AssertWebElement - WebElement was displayed!
[INFO ] 2020-01-12 10:12:38.110 [TestNG-tests-1] generic.assertions.AssertWebElement - Checking if WebElement has text: Invalid username or password. Signon failed.
[INFO ] 2020-01-12 10:12:38.110 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to find element with locator By.cssSelector: #Content ul[class='messages'] li
[INFO ] 2020-01-12 10:12:38.120 [TestNG-tests-1] driver.listeners.DriverEventListener - Found element with locator By.cssSelector: #Content ul[class='messages'] li
[INFO ] 2020-01-12 10:12:38.120 [TestNG-tests-1] driver.listeners.DriverEventListener - Trying to get text for WebElement
[INFO ] 2020-01-12 10:12:38.131 [TestNG-tests-1] driver.listeners.DriverEventListener - Taken text of WebElement. Text wast Invalid username or password. Signon failed.
[INFO ] 2020-01-12 10:12:38.132 [TestNG-tests-1] generic.assertions.AssertWebElement - WebElement had expected text!
[INFO ] 2020-01-12 10:12:38.132 [TestNG-tests-1] utils.testng.listeners.TestListener - Test asUserTryToLogInWithIncorrectLoginAndPassword passed successfully
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 5.339 s - in TestSuite
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.196 s
[INFO] Finished at: 2020-01-12T10:12:39+01:00
[INFO] ------------------------------------------------------------------------
[Pipeline] sh
+ docker-compose down
Stopping test_firefox_1 ...
Stopping test_chrome_1 ...
Stopping selenium-hub ...
[3B [1A [2K
Stopping selenium-hub ... [32mdone [0m
[1BRemoving test_firefox_1 ...
Removing test_chrome_1 ...
Removing selenium-hub ...
[1A [2K
Removing selenium-hub ... [32mdone [0m
[1B [3A [2K
Removing test_firefox_1 ... [32mdone [0m
[3B [2A [2K
Removing test_chrome_1 ... [32mdone [0m
[2BRemoving network test_default
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] script
[Pipeline] {
[Pipeline] allure
[Test] $ "D:\Program Files (x86)\Jenkins\tools\ru.yandex.qatools.allure.jenkins.tools.AllureCommandlineInstallation\allure\bin\allure.bat" generate "D:\Program Files (x86)\Jenkins\workspace\Test\target\allure-results" -c -o "D:\Program Files (x86)\Jenkins\workspace\Test\allure-report"
Report successfully generated to D:\Program Files (x86)\Jenkins\workspace\Test\allure-report
Allure report was successfully generated.
Creating artifact for the build.
Artifact was added to the build.
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Podsumowanie
Dzięki zastosowaniu Docker Selenium mamy możliwość:
- Łatwego skalowania ilością Nodów Selenium i ich konfiguracją w ramach docker-compose.yml
- Pełną kontrolą na infrastrukturą Selenium GRID,
- Wykonanie na jednej maszynie, co zmniejsza koszt, zwiększa stabilność, ułatwia debugowanie.
Potrzebujesz więcej informacji?
Artykuł powstał na bazie kursu Automatyzacja testów z wykorzystaniem Selenium.
O Autorze
Nazywam się Mateusz Ciołek i od 2011 roku zajmuję się testowaniem oprogramowania ze specjalizacją w automatyzacji testów.
Dyskusja i komentarze
Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.