Java dla Testerów 14. Dziedziczenie

W tej lekcji omówimy sobie dziedziczenie w Javie. Być może miałaś lub miałeś okazję widzieć gdzieś omówienie dziedziczenia na przykładzie klasy zwierzę albo klasy pojazd, bo są to bardzo popularne przykłady. W tym filmie pokażę Ci to jednak na przykładzie związanym już z testami.

W przykładzie wspominam o POM, czyli o Page Object Model. POM to wzorzec projektowy używany powszechnie w testach Selenium. Charakteryzuje się on tym, że klasy odpowiadające za reprezentację poszczególnych stron aplikacji webowej są oddzielone od testów. Metody testowe znajdują się w klasach odpowiadających za testy, a metody związane z wykonywaniem jakichś konkretnych akcji na podstronach, znajdują się w klasach Page Object.

Oczywiście w tej lekcji nie będziemy jeszcze wprowadzać Selenium ale będziemy pracować na „zaślepkach”, czyli klasach i metodach udających trochę POM. Zobaczysz tam też klasę nazwaną BasePage – to będzie nasza klasa bazowa dla innych klas Page Object. Dziedziczenie omówimy sobie własnie na przykładzie tej klasy i przykładowej klasy Page Object. Klasę Base Page możemy porównać właśnie do klasy Zwierzę, będącej klasą bazową np. dla klasy Kot czy Pies.

A czym to dziedziczenie jest? Dziedziczenie to cecha programowania obiektowego, która pozwala jednej klasie na dziedziczenie pól i metod innej klasy, a w konsekwencji na wywoływanie tych metod na obiekcie klasy dziedziczącej.  Klasa bazowa to klasa, która opisuje jakiś ogólny zestaw cech jakiegoś typu obiektu, np. podana w przykładzie BasePage. Taka klasa może mieć np. metodę odpowiadającą za przejście na daną stronę czy pobranie tytułu strony. Są to metody, które chcemy móc wywoływać na obiektach wszystkich klas Page Object, czyli na obiektach klas reprezentujących konkretne strony aplikacji webowej. Klasy potomne (nazywane też pochodnymi) to klasy, które dziedziczą z klasy bazowej. W naszym przykładzie klasami potomnymi są klasy reprezentujące właśnie konkretne strony, czyli np. ProductPage (klasa produktu). Żeby klasa ProductPage dziedziczyła po klasie BasePage, to w definicji klasy ProductPage musimy dodać extends BasePage.

public class ProductPage extends BasePage {   
}

Skutkiem dodania tej informacji będzie możliwość użycia metod klasy BasePage na obiekcie klasy ProductPage. Oznacza to, że na takim obiekcie możemy na przykład użyć metody goTo() znajdującej się w klasie BasePage i służącej do przejścia na daną stronę.

public class BasePage {
    void goTo(String pageUrl){
        System.out.println("Going to page.");
    }   
}
import org.junit.jupiter.api.Test;

public class Tests {
    @Test
    public void goToProductPage(){
        ProductPage productPage = new ProductPage();
        productPage.goTo("url strony jakiegoś produktu");        
    }
}

Nie zawsze użycie metod czy pobranie wartości pól klasy bazowej jest możliwe w klasie potomnej. Będzie to również zależało od modyfikatorów dostępu. Jeżeli metoda albo pole będzie miało w klasie bazowej modyfikator private, to w powyższy sposób to nie zadziała. Powyższy kod dokładnie w takiej formie, w jakiej go pokazałam nie zadziała również, jeżeli klasy BasePage i ProductPage będą w innym pakiecie ale o tym wszystkim dokładniej powiem w kolejnej lekcji dotyczącej modyfikatorów dostępu.