Selenium 71. Page Object Model: jak zacząć budować własny framework testowy

Interesuje Cię ten kurs?

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

W tej lekcji zaczniemy tworzyć swój własny framework testowy. Pokażę Ci jak zacząć i jak IntelliJ może nam oszczędzić pracy. Przepiszemy jeden test i stworzymy dwie klasy Page Object: CartPage i ProductPage.

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

W poniższych klasach poprawiłam nazwę pakietu z PageObjetcs na PageObjects. Zmień to również u siebie – wystarczy, że klikniesz na nazwę tego pakietu (folderu) na drzewku po lewej stronie, wybierzesz Refactor>Rename.

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 testowa: CartTests

Ukryta treść

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

Wsparcie merytoryczne

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

  1. Trochę  inaczej napisałem testy, więc i trochę inne metody wykorzytuję. Poniżej jedna z przykładowych:

    @Test
    public void shouldAddProductToCartFromCategoryPage(){
    String givenCategoryName = "Wspinaczka";
    String givenProductName = "Wspinaczka Via Ferraty";
    HomePagePOM homePagePOM = new HomePagePOM(driver);

    HashSet<String> productsInCart = homePagePOM.goToShopPage().goToCategory(givenCategoryName).addProductToCartFromCategory(givenProductName).goToCart(givenProductName).productsInCart();
    Assertions.assertTrue(productsInCart.contains(givenProductName), "Cart not contain selected product!");
    }

    I pytanie: jak to zapisać jeśli jednak nie chciałbym tego chainować, czyli zapisywać kroki w oddzielnych liniach, coś w stylu:
     
    homePagePOM.goToShopPage(); //zwraca new ShopPage(driver)
    shopPage.goToCategory(givenCategoryName); //zwraca new CategoryPage(driver)
    categoryPagePOM.addProductToCartFromCategory(givenProductName); //zwraca new CategoryPage(driver) - bo nie zmieniamy strony
    itd..
    i dopiero na końcu robię
    HashSet<String> productsInCart = cartPagePOM.productsInCart();

     

    Odpowiedz
  2. Dzięki za feedback 🙂 Po przemyśleniu zdecydowałem się trzymać jednak takiej notacji:

    productsInCart = homePagePOM.goToShopPage()
                                .goToCategory(givenCategoryName)
                                .addProductToCartFromCategory(givenProductName)
                                .goToCart(givenProductName)
                                .productsInCart();
    
    Assertions.assertTrue(productsInCart.contains(givenProductName), "Cart not contain selected product!");

    POM w nazwie jest dla lepszej czytelnoci w IDE, równolegle dłubie sobie też ten sam projekt w page factory i tam mam końcówki PF (wiem że w różnych package'ach mogą być te same nazwy klas ale tak jest mi wygodniej i czytelniej).

    goToCart z parametrem wyszukuje button pod konkretnym produktem bo takich buttonów może być kilka jeśli dodałem kilka produktów, a mi chodzi o ten pod konkretnym produktem.

    Odpowiedz
  3. Cześć, takie pytanko mi się nasunęło: czy nie moglibyśmy zrobić metody goTo w ten sposób?

    public ProductPage goTo(String productUrl) {
            driver.navigate().to(productUrl);
            return this;
        }

    Wiem że to w sumie szczegół, ale jestem ciekaw czy takie rozwiązanie byłoby ok 🙂

    Odpowiedz
  4. Cześć
    Jeśli chodzi o usuwanie nieużywanych importów, to dla mnie bardzo wygodny jest skrót Ctrl + Alt + O - usuwa nieużywane importy. Oprócz skrótu Ctrl + Alt + L chyba najczęściej używam. Mam nadzieję, że komuś się przyda.

    Mam pytania do lekcji i z góry przepraszam jeśli za bardzo się czepiam:
    1. Skoro metoda getProductsAmount pobiera z koszyka elementy o konkretnym ID, to czy nie lepsza byłaby nazwa getProductAmount (pobierz ilość produktu - bo wskazujemy konkretny produkt), zamiast getProductsAmount (pobierz ilość produktów)?
    2. W teście addToCartFromProductPageTest() sprawdzamy czy w koszyku znajduje się dokładnie jeden element o podanym ID. Nie sprawdzamy natomiast ogólnie zawartości koszyka tzn nie sprawdzamy czy znajdują się w nim inne produkty, których przecież nie powinno w nim być. Jestem w stanie sobie wyobrazić taki błąd, że po jakiś zmianach button na stronie produktu dodający do koszyka dodaje po jednej sztuce wszystkich produktów ze sklepu zamiast tego jednego wyświetlanego produktu. Wtedy taki test i tak przejdzie i nie wykryje błędu.
    Co myślisz o pomyśle żeby oprócz sprawdzenia czy ilości pozycji o danym ID jest równa jeden, sprawdzić też czy ogólna ilość pozycji w koszyku jest równa jeden?
    3. Zastanawiam się jakie dane przekazywać z Page Object do asercji w teście. Zapytam na przykładzie.
    Jak myślisz czy przekazywać do asercji wielkość listy towarów jako int i sprawdzać czy jest ==1, czy równie dobrze jest przekazać listę i w asercji zrobić listaProduktów.size()==1 ?

    Odpowiedz
      • ad. 3 Ja jeśli miałbym tylko jeden test w którym sprawdzam wielkość tej listy, to bym użył listaProduktów.size() , a jeśli potrzebowałbym więcej razy wielkość tej listy, to użyłby metody od razu zwracającej int z jej wielkością, ale rozumiem, że każdy może mieć swoje podejście.
        Dzięki za odpowiedzi 🙂

        Odpowiedz