Как правильно сделать структуру и наследование в проекте?

Здравствуйте, подскажите пожалуйста как правильно делать наследование?

У меня есть клас DriverSetup, в нем задается конфигурация(драйвер, браузер, таймаут, расширение экрана, url, и другие настройки).
Есть пакет objects, где у меня мои page objects (локаторы, методы для страницы).
Есть пакет tests, в нем собственно тесты.
В каждом тестовом классе делаю наследование от DriverSetup и создаю обьект определенной страницы.Например

public class LoginPageTests extends DriverSetup {

    private objects.LoginPage loginPage;
   
    @BeforeClass public void setUp() {

        loginPage = new objects.LoginPage();
}

  @Test
       public void checkSuccessUserAuthorization() {

        loginPage.enterEmail(userEmail);
        loginPage.enterPassword(userPassword);
......
}

Как по мне, наверное лучше мои LoginPageObjects extends DriverSetup, а в пакете с тестамы делать LoginPageTests extends LoginPageObjects.
Подскажите, как вы делаете у себя на проекте и как правильно делать?Спасибо!

public class LoginPageTests extends DriverSetup {

Вы хотели, наверно, написать? Всё правильно у вас по смыслу.
Классы с тестами с классами пейджей не надо связывать.

но тогда приходиться создавать объекты в каждом тестовом классе.Это нормальная практика?
Делать каждый раз

private objects.LoginPage loginPage;

     loginPage = new objects.LoginPage();

и обращаться к методу через объект loginPage.enterEmail вместо просто enterEmail ?

и второй вопрос классы с тестами можна связывать с классом настройками драйвера?

Да так.

Можно.
Можно сделать ещё один класс между этими двумя классами (типа LoginPageTests extends BaseTestsClass extends DriverSetup), куда вынести все

public objects.LoginPage loginPage = new objects.LoginPage();

и использовать их в тестах.

1 лайк

Cпасибо, кажется разобрался.

Еще такой вопрос, где и как лучше использовать интерфейсы в тестах? Я так понимаю, если к примеру у меня есть input email на странице Login page и на странице Registration page, чтобы не создавать два одинаковых метода, к примеру enterEmail() в объекте Login page и enterEmail() в объекте Registration page, создают дефолтный метод в интерфейсе, и потом его используют?
Я правильно понимаю?Возможно еще есть преимущество?

Как же одинаковых? А если локаторы элементов изменятся? Не заморачиватесь по поводу интерфейсов.

если локатор изменится переопределить метод

Да, идея в целом правильная.
Единственное, что: я бы впилил driverFactory паттерн (если будет необходимость тестировать на разных браузерах, а рано или поздно она возникает) и ещё отнаследовал классы страниц не от DriverSetup, а от BasePage, в конструкторе которой впилил бы обращение к методам DriverSetup - это логичнее по смыслу. Страницы должны наследоваться от базовой страницы, на которой должны быть методы по управлению страницами (тот же load, к примеру), а не от непонятного класса настройки драйвера.

Интерфейсы имеет смысл использовать для группы компонентов, общих для нескольких страниц.
Например, табличка.
В интерфейсе прописываем методы по работе с табличкой (например, поиск значения эл-та в [i,j] ячейке таблички). Тогда наша страница будет иметь вид:

public class MyPage extends PageBase implements MyTable {
}

Таким образом, методы по работе с табличкой на странице будут доступны сразу же.

2 лайка