Selenium 85. Synchronizacja w Singletonie i konfiguracja bez Singletona

Interesuje Cię ten kurs?

Dołącz do listy mailingowej, a poinformuję Cię o otwarciu zapisów.

W tej lekcji dokończymy temat Singletona i poruszymy sobie temat, o którym wspomniałam w poprzedniej lekcji, czyli synchronizacja w Singletonie.

Uwaga: plik z projektem testowym, na którym pracujemy w lekcjach dotyczących POM wymaga uzyskania dostępu. Dostaniesz go tutaj.

Poruszymy temat sekcji krytycznej oraz bloku synchronizowanego. Zobaczysz też co daje dodanie przed zmienną słówka volatile. Gdy już zamkniemy temat Singletona wrócimy do konfiguracji i przerobimy tą klasę na taką, która nie używa Singletona i pokażę Ci jak to ładnie rozwiązać.

Dodatkowo posłużymy się adnotacją @TestInstance(Lifecycle.PER_CLASS) w JUnit 5. Adnotacja ta sprawi, że wszystkie metody testowe będą korzystały z tej samej instancji klasy testowej. Domyślnie, gdy nie dodamy tej adnotacji, nowa instancja jest tworzona dla każdej metody testowej. Oznacza to, że naszych testów nie będziemy mogli w przyszłości zrównoleglić na poziomie metod, czyli nie będziemy mogli uruchamiać testów w jednej klasie równolegle. Żeby to zrobić będziemy musieli przenieść inicjalizację konfiguracji z BeforeAll to BeforeEach. Natomiast nadal będziemy mogli uruchamiać testy równolegle na poziomie klas (czyli testy z kilku różnych klas testowych nadal będą mogły być uruchamiane równolegle).

Zaktualizowane klasy

Klasa testowa: PaymentsTests

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa testowa: CartTests

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa testowa: BaseTest

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: CheckoutPage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: CartPage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: ProductPage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: CategoryPage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: BasePage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: DemoFooterPage

(czyli nasza stopka w POM)

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: HeaderPage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa Page Object: OrderReceivedPage

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa: DriverFactory

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Enum: Browser

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Klasa: ConfigurationManager (wzorzec Singleton)

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Configuration.properties

Ukryta treść

Nie masz dostępu do tego kursu. Wykup dostęp albo zaloguj się, by móc zobaczyć pełną lekcję.

Lista lekcji dotyczących budowy Frameworka:

Wsparcie merytoryczne

Nie masz aktywnego członkostwa. Wykup dostęp albo Zaloguj się, by móc zadawać pytania.

  1. Cześć Ela, mam dwa pytania:
    1) Czy klasy BaseTest i BasePage nie powinny być abstrakcyjne?
    2) Czy te dwie poniższe linijki z klasy BaseTest można przenieść do metody @BeforeAll? Czy są jakieś przeciwskazania?
    [java]
    DriverFactory driverFactory = new DriverFactory();
    driver = driverFactory.create(configuration);
    [/java]

    Odpowiedz
    • Halko! BasePage powinna być abstrakcyjna, zresztą pokazuję to w lekcjach dotyczących BasePage, taki ze mnie śmieszek widzę, że tutaj tego nie zrobiłam 😀 BaseTest też w zasadzie można, tylko upewnij się, że testy się odpalają poprawnie. Chodzi o to, żeby sprawdzić czy JUnit sobie poradzi z nadrzędną klasą testową, która jest abstrakcyjna.

      Co do drugiego pytania: to musi iść do BeforeEach, bo tam tworzymy nową instancję drivera, a chcemy mieć “świeżego” drivera w każdym teście. Używanie tej samej instancji drivera jest niebezpieczną praktyką – mogą Ci zostać jakieś śmieci w sesji po poprzednim teście albo w ogóle driver z różnych powodów może umrzeć i wtedy wszystkie testy umrą też. To by też utrudniło, jeżeli nie uniemożliwiło w przyszłości odpalanie testów równolegle.

      Odpowiedz
  2. Cześć,
    w tej lekcji dużo zmian jest spowodowanych umożliwieniem późniejszego odpalania testów równolegle.
    Czy jest jakaś lekcja gdzie omawiasz konfigurację i odpalanie testów Selenium w JUnit równolegle?

    Odpowiedz
  3. Cześć,
    udało mi się opanować podstawy uruchamiania testów równolegle w JUnit zarówno w terminala z mavena jak i w IntelliJ.
    Z zastosowaniem singletona wszystko śmiga, ale po przejściu na użycie @BeforeAll z adnotacją @TestInstance(TestInstance.Lifecycle.PER_CLASS) niestety testy z tej samej klasy uruchamiają się jednowątkowo.
    Z użyciem tej adnotacji każda klasa z testami może mieć jeden wątek i jest to dla mnie zrozumiałe po tym jak wytłumaczyłaś jak działa ta adnotacja.
    Zastanawiam się jednak czemu nie zmieniłaś w @BeforeAll metody getConfiguration() na statyczną?
    W lekcji [od 13:55] tłumaczysz, że po zmianie tej metody na statyczną pole ConfigurationManager configuration też musiałoby być statyczne i dlatego nie możemy zmienić tej metody na statyczną. Ale właściwie dlaczego to pole configuration nie może być statyczne?
    Ja usunąłem adnotację @TestInstance(TestInstance.Lifecycle.PER_CLASS), metodę getConfiguration() zrobiłem statyczną i pole ConfigurationManager configuration też oznaczyłem jako statyczne i wszystkie testy mi działają. Wszystkie testy wykonują się prawidłowo i mogę puszczać testy z tej samej klasy wielowątkowo. Uruchamiając testy jednowątkowo też wszystko działa jak należy.
    Jest jakiś powód dla którego pole ConfigurationManager configuration nie może być statyczne skoro testy się uruchamiają?

    Odpowiedz
      • Cześć, może źle Cię zrozumiałem w nagraniu, bo opowiadając podświetliłaś nazwę tego pola i tak to opatrznie zrozumiałem.
        W każdym razie czy możesz mi wytłumaczyć czemu nie zdecydowałaś się na zrobienie tego pola statycznym, tylko zastosowałaś adnotację @TestInstance(TestInstance.Lifecycle.PER_CLASS), która ogranicza wykonywanie testów równolegle?
        W 14:04 mówisz “Chodzi o to, że tworzymy tutaj obiekt jakiejś klasy, a ta metoda jest statyczna i tak się nie da”. Nie do końca zrozumiałem czy są jakieś przeciwwskazania do oznaczenia metody getConfiguration() i pola configuration jako statyczne?

        Odpowiedz
        • Nie zdecydowałam się na zrobienie tego pola statycznym, tylko zastosowałam adnotację @TestInstance(TestInstance.Lifecycle.PER_CLASS), bo rozwiązania które przygotowałam (czyli po prostu zamiana singletona na nie singletona) nie planowałam użyć w statycznym kontekście. Nie umiem Ci teraz powiedzieć, czy tutaj mogą się pojawić jakieś nieprzewidziane konsekwencje. Gdybym planowała zrobić to pole statycznym, to zbudowałabym całość od nowa mając takie założenie w głowie.

          Odpowiedz