Większość projektów, w których automatyzowane są testy aplikacji internetowych, wymaga wykonywania skryptów z wykorzystaniem różnych przeglądarek. Manualne zarządzanie konfiguracją, wersjami sterowników przeglądarek i odpowiednim uruchomieniem testów jest czasochłonne i podatne na błędy, dlatego warto używać narzędzi automatyzujących ten proces. Mechanizmy biblioteki WebDriverManager
oraz frameworku JUnit 5
umożliwiają testowanie na różnych przeglądarkach bez wprowadzania zmian w kodzie, dzięki automatycznemu dobieraniu odpowiedniego sterownika oraz wykorzystaniu zewnętrznej konfiguracji uruchamiania. Skuteczność tych rozwiązań pokażę modyfikując projekt testów aplikacji TodoMVC
, w którym wsparcie dla różnych przeglądarek było jak do tej pory całkowicie manualne.
O serii
Czytasz część 4 serii artykułów na temat automatyzacji testów aplikacji internetowej TodoMVC. Pozostałe części:
- Część 1 - JUnit 5 i Selenium - Wprowadzenie do projektu automatycznych testów aplikacji internetowej
- Część 2 - JUnit 5 i Selenium - Odpowiedzialność metod testowych
- Część 3 - JUnit 5 i Selenium - Wprowadzenie do wzrorca Page Object
- Część 5 - JUnit 5 i Selenium - klasa PageFactory z pakietu support biblioteki Selenium
Kod źródłowy
Kod źródłowy opracowany w poprzednim artykule znajduje się w repozytorium Git
: https://gitlab.com/qalabs/blog/junit5-selenium-todomvc-example w branchu 3-page-objects
. Zmiany opisywane w tym artykule znajdują się w branchu 4-configuration
.
Aktualizacja bibliotek i narzędzi w projekcie
Od publikacji poprzedniego artykułu z serii minęło już kilka miesięcy, więc wykorzystywane biblioteki i narzędzia w międczyczasie zostały zaktualizowane. Warto zacząć zmiany w projekcie od ich aktualizacji.
Java 12
Obecnie (maj 2019) najnowszą dostępną wersją Java SDK
jest 12, dlatego zaktualizujemy do niej tworzony projekt. W celu zmiany wersji Java
zmodyfikuj plik build.gradle
i zmień wartość właściwości sourceCompatibility
na 12
. Dla porządku warto przy tym zauważyć, że Java 12
nie jest wersją z długim okresem wsparcia (ang. long time support, LTS), a ostatnia wersja LTS to Java 11
.
Tip: W razie problemów upewnij się, że masz w swoim systemie operacyjnym zainstalowane
Java SDK
w wersji 12 i że jest ono poprawnie skonfigurowane wIntelliJ
. Instrukcje do konfiguracji i weryfikacji środowiska znajdziesz w naszych wcześniejszych artykułach dla systemu Windows: https://blog.qalabs.pl/java/przygotowanie-srodowiska/ oraz macOS: https://blog.qalabs.pl/narzedzia/java-selenium-macos/.
Gradle Wrapper, JUnit i Selenium
W kolejnym kroku zaktualizujemy również:
Gradle Wrapper
do wersji5.4.1
JUnit
do wersji5.4.2
Selenium
do wersji3.141.59
Żeby ułatwić sobie to zadanie w przyszłości, dokonamy przy tym małego usprawnienia w pliku build.gradle
, to znaczy dodamy w nim właściwości z numerami wersji poszczególnych bibliotek, żeby następnie wykorzystać je przy podawaniu nazw zależności w bloku dependencies
. W tym celu w pliku build.gradle
dodaj następujący blok:
1 | ext { |
…a następnie wykorzystaj utworzone w ten sposób właściwości w dalszej części skryptu, zastępując nimi numery wersji:
1 | dependencies { |
Tip: Aby powyższa zmiana została zastosowana w
IntelliJ
, konieczne jest odświeżenie konfiguracji projektu.
Podstawowa konfiguracja logowania
Zanim przejdziemy do głównego tematu tego artykułu, to znaczy automatycznej konfiguracji i uruchomienia testów dla różnych przeglądarek, warto jeszcze dodać w projekcie konfigurację logowania. Do logowania użyjemy biblioteki Logback
, która została zaprojektowana jako następczyni popularnej biblioteki Log4j
. W tym celu w pliku build.gradle
dodaj następujące zależności:
1 | ext { |
Aby skonfigurować logera, w katalogu src/test/resources
utwórz plik logback.xml
z następującą zawartością:
1 |
|
Powyższa konfiguracja zapewnia logowanie do konsoli na tak zwane standardowe wyjście.
Tip: Więcej na temat biblioteki
Logback
oraz jej konfiguracji dowiesz się z oficjalnej dokumentacji projektu: https://logback.qos.ch/
Zarządzanie sterownikami przeglądarek
Wykorzystanie WebDriverManager
WebDriverManager
to biblioteka umożliwiająca automatyczne zarządzanie binariami sterowników do przeglądarek wymaganymi przez Selenium WebDriver
. Szerszy opis tej biblioteki znajdziesz w artykule Selenium WebDriverManager dla projektów w Java - pierwsze kroki.
Dodanie biblioteki WebDriverManager
do projektu jest bardzo proste, ponieważ można ją znaleźć w centralnym repozytorium Maven, dzieki czemu można ją dodać jako zależność w projektach opartych zarówno o Maven
jak i Gradle
.
Na początek dodamy odpowiednie wpisy w pliku build.gradle
, wykorzystując opisane wyżej podejście z umieszczeniem numeru wersji w osobnej właściwości:
1 | ext { |
Aby skorzystać z funkcjonalności automatycznego zarządzania, należy użyć statycznych metod klasy WebDriverManager
, które pozwalają na konfigurację wspieranego przez bibliotekę sterownika. W naszym projekcie podstawową konfigurację przeglądarki na potrzeby testów zawiera klasa Browser
, stąd dodamy do niej kod wykorzystujący WebDriverManager
:
1 | public class Browser { |
Ponieważ statyczny blok jest wykonywany podczas ładowania klasy do pamięci, to powyższy kod wykona się jeszcze przed uruchomieniem testów. To rozwiązanie nie jest docelowe, użyłem go, aby w szybki sposób i z nieznacznymi modyfikacjami w kodzie wykorzystać WebDriverManager
. W dalszej części artykułu rozwiązanie zostanie usprawnione.
Selenium Manager
(od Selenium
w wersji 4.6
)
Selenium Manager
to nowe narzędzie, które automatycznie zarządza sterownikami i pomaga w łatwym uruchomieniu Selenium
. Selenium Manager
skonfiguruje sterowniki dla przeglądarek Chrome
, Firefox
i Edge
, jeśli nie są one dostępne w PATH
, podobnie jak Webdriver Manager
. Narzędzie to jest dostępne od Selenium
w wersji 4.6
.
Więcej informacji na temat
Selenium Manager
znajdziesz na naszym blogu w artykule Selenium Manager - łatwiejszy start z automatyzacją testów Selenium dzięki nowej funkcjonalności.
Uruchomienie testów
W tym miejscu warto sprawdzić, jak wprowadzone zmiany wpłynęły na wykonanie testów. W tym celu uruchom testy i obserwuj wpisy w konsoli, a w logach powinna pojawić się informacja pochodząca z klasy WebDriverManager
:
1 | i.g.b.w.WebDriverManager - Using chromedriver 74.0.3729.6 (since Google Chrome 74 is installed in your machine) |
Testy wykonują się poprawnie, chociaż nie trzeba już pobierać sterowników i instalować ich ręcznie w systemie, ponieważ dba o to WebDriverManager
.
Konfiguracja typu przeglądarki
W aktualnym rozwiązaniu aby zmienić typ przeglądarki, na której wykonywane są testy (np. Chrome
na Firefox
) musimy zmodyfikować kod w klasie Browser
i uruchomić testy ponownie. Można znacznie ułatwić sobie to zadanie i wyeliminować konieczność modyfikacji kodu testów poprzez przekazanie typu przeglądarki jako parametru konfiguracyjnego przy uruchomieniu testów.
Typ przeglądarki jako parametr konfiguracyjny
Parametry konfiguracyjne to pary klucz-wartość, które dostarczymy do silnika testów JUnit 5
za pomocą właściwości systemowej JVM
. Niestety, Gradle
aktualnie nie dostarcza dedykowanego sposobu na przekazywanie parametrów do silnika testów, trzeba zatem przekazać je bezpośrednio ze skryptu build.gradle
.
Aby to osiągnąć, zmodyfikujemy zadanie test
w pliku build.gradle
:
1 | test { |
Powyższy kod przekaże do silnika testów JUnit 5
wartość zmiennej systemowej, którą pobierze z parametru projektu. Wartość parametru definiowana jest podczas uruchomienia Gradle
za pomocą parametru -P
. Dzięki takiemu rozwiązaniu będziemy mogli uruchomić testy przekazując typ przeglądarki jako parametr uruchomienia:
./gradlew clean test -Pbrowser=firefox|chrome|safari
Ponieważ może się zdarzyć, że wartość parametru nie zostanie przekazana za pomocą zmiennej systemowej, na przykład podczas uruchomienia testów w IDE, dlatego zdefiniujemy wartość domyślną, dodając parametr browser
do pliku src/test/resources/junit-platform.properties
:
browser=chrome
Własne rozszerzenie JUnit 5
Tak zdefiniowany parametr wykorzystamy w testach z pomocą własnego rozszerzenia JUnit 5
, które na podstawie wartości podanej w konfiguracji zainicjuje odpowiedni sterownik (np. ChromeDriver
, FirefoxDriver
) i udostępni go w testach.
Istnieje wiele mechanizmów rozszerzeń JUnit 5
, w zależności od potrzeb mogą to być między innymi:
- Conditional Test Execution - określenie warunków decydujących o uruchomieniu testów
- Parameter Resolution - rozwiązywanie parametrów wstrzykiwanych do testów
- Test Lifecycle Callbacks - “wpinanie się” w odpowiednie kroki cyklu życia testu
- Test Result Processing - przetwarzanie rezultatów wykonania testów
Tworząc to rozszerzenie wykorzystamy mechanizm rozwiązywania parametrów. Zadaniem tego rozszerzenia będzie utworzenie i dostarczenie argumentu typu Browser
dla metod @BeforeEach
i @AfterEach
w klasie testowej. Rozszerzenie będzie również wykorzystywać klasę WebDriverManager
, która dostarczy odpowiedni sterownik przeglądarki.
Klasa pomocnicza WebDriverFactory
Budowanie rozszerzenia rozpoczniemy od stworzenia klasy pomocniczej WebDriverFactory
, która będzie odpowiedzialna za utworzenie obiektu WebDriver
na podstawie wartości parametru browser
. Dostępne wartości tego parametru wraz z odpowiadającymi im klasami sterownika są z góry zdefiniowane w mapie drivers
. Utworzenie instancji odpowiedniej klasy jest realizowane z użyciem klasy pomocniczej ReflectionUtils
pochodzącej z JUnit 5
. WebDriverFactory
jest więc prostą fabryką używającą do realizacji swojego zadania mechanizmów refleksji w Java
.
1 | class WebDriverFactory { |
Klasa BrowserParameterResolver
Na właściwe rozszerzenie składać się będzie klasa BrowserParameterResolver
, która będzie wykorzystywać interfejsy tak zwanego Extension API
, umożliwiającego rozszerzeniom JUnit 5
definiowanie kodu wykonywanego w określonych momentach cyklu życia testu. Nasze rozszerzenie będzie implementować interfejsy BeforeAllCallback
, ParameterResolver
oraz AfterEachCallback
.
Metoda interfejsu BeforeAllCallback
Użycie interfejsu BeforeAllCallback
wymaga zaimplementowania metody beforeAll
, która zostanie wykonana przez JUnit 5
przed wykoniem pierwszej metody w klasie testowej. W naszym przypadku metoda ta jest odpowiedzialna za konfigurację sterownika dla właściwego typu przeglądarki. Jest ona rozszerzeniem utworzonego wcześniej statycznego inicjalizatora klasy Browser
, który teraz należy z niej usunąć. Wartość parametru konfiguracyjnego określającego typ przeglądarki jest pobierana z tak zwanego kontekstu rozszerzenia przy pomocy prywatnej metody getConfigParameter
.
Metody interfejsu ParameterResolver
Interfejs ParameterResolver
służy dynamicznemu rozwiązywaniu parametrów w trakcie wykonywania testów. W naszym przypadku metoda supportsParameter
weryfikuje, czy parametr, który ma zostać rozwiązany przez BrowserParameterResolver
, jest typu Browser
. Metoda resolveParameter
pobiera natomiast z kontekstu rozszerzenia obiekt Browser
. Jeżeli obiekt nie istnieje, zostanie utworzony z wykorzystaniem wcześniej utworzonej klasy WebDriverFactory
, ale metoda resolveParameter
zostanie wykonana tylko jeżeli metoda supportsParameter
zwróci wartość true
.
Metoda interfejsu AfterEachCallback
Metoda afterEach
z interfejsu AfterEachCallback
zostanie wykonana po każdej metodzie testowej w klasie testowej. W naszym przypadku w metodzie z kontekstu rozszerzenia pobierany jest obiekt Browser
, a następnie wywoływana jest na nim metoda quit
zamykająca przeglądarkę.
Pełna implementacja opisanego wyżej kodu jest następująca:
1 | public class BrowserParameterResolver implements BeforeAllCallback, ParameterResolver, AfterEachCallback { |
Tip: Więcej o rozrzerzeniach w JUnit 5 dowiesz się z oficjalnej dokumentacji: https://junit.org/junit5/docs/current/user-guide/#extensions
Użycie rozszerzenia w TodoMvcTests
W celu wykorzystania nowoutworzonego rozszerzenia należy użyć adnotacji @ExtendWith
wskazując typ rozszerzenia. Kolejnym krokiem jest usunięcie metody afterEach
oraz modyfikacja metody beforeEach
:
1 |
|
Metoda beforeEach
akceptuje parametr typu Browser
, który zostanie dostarczony przez rozszerzenie BrowserParameterResolver
. Metoda afterEach
została usunięta, gdyż zamykanie przeglądarki po każdej metodzie testowej zostało już zaimplementowane w rozszerzeniu.
Tip: O wstrzykiwaniu argumentów do metod testowych dowiesz się więcej z artykułu (JUnit 5 - Pierwsze kroki)[https://blog.qalabs.pl/junit/junit5-pierwsze-kroki/]
Uruchomienie testów
Nadszedł czas na przetestowanie rozszerzenia. W tym celu uruchom wiersz poleceń i w katalogu projektu wykonaj polecenie:
./gradlew clean test -Pbrowser=firefox
Dzięki wprowadzonym usprawnieniom w tym przypadku testy powinny uruchomić się w przeglądarce Firefox
, a w celu użycia innej przeglądarki nie trzeba nic zmieniać w kodzie, wystarczy tylko zmienić wartość parametru uruchomienia.
Repozytorium Git projektu
Kod źródłowy opracowany w artykule znajduje się w repozytorium Git
: https://gitlab.com/qalabs/blog/junit5-selenium-todomvc-example w branchu 4-configuration
.
Zobacz również
Selenium WebDriverManager
dla projektów wJava
- pierwsze kroki - https://blog.qalabs.pl/junit-selenium/selenium-webdriver-manager-pierwsze-kroki- Dokumentacja
Extension API
wJUnit 5
- https://junit.org/junit5/docs/current/user-guide/#extensions