Реструктуризация WebDriver Java кода или как перейти от низкоуровневого кода к высокоуровнему

Пытаюсь сделать переход от низкоуровневого кода к высокоуровнему.
Пока мои тесты это длинные нечитаемые простыни. В связи с этим вопросы возникают, как лучше сделать я пока не знаю, более опытные в этом деле, надеюсь, помогут.

Есть у меня три кнопки в разных местах приложения
driver.findElement(By.xpath("//div[@id=\"tab_1\"]//button[@id=\"btn_add\"]")).click();
driver.findElement(By.xpath("//div[@id=\"tab_2\"]//button[@id=\"btn_add\"]")).click();
driver.findElement(By.xpath("//div[@id=\"tab_3\"]//button[@id=\"btn_add\"]")).click();

Это абсолютно одинаковые кнопки “Добавить”, просто на разных вкладках.

Как правильнее делать, три разных метода или один метод и разные локаторы для него?

Так

clickDayTabButton();
clickEvnTabButton();
clickPartTabButton();

Или так

clickTabButton(locator);

Я думаю, что правильнее второй вариант, зачем плодить почти одинаковые методы, но могу ошибаться и это аукнется чем-нибудь нехорошим в будущем

Еще если я делаю вторым вариантом, то в тестовом классе появляется этот самый локатор, что не совсем красиво и, скорее всего, неправильно, потому что не должно быть признаков кода, только логика

Вот о чем я, например, тестовый класс

public class AddApplicantDay{
@Test
clickTabButton("//div[@id=\"tab_1\"]//button[@id=\"btn_add\"]

И общий суперкласс

public class TestBase {
clickTabButton(locator);

Если я все делаю правильно, то как спрятать этот локатор в виде кода в тестовом классе, когда делаю Refactor -> Introduce Parametr, то локатор пропадает и я его не могу отыскать (

PageObject + BasePage решат все ваши вопросы.

1 лайк

Если вы решили заняться рефакторингом, то начните с создания page object’ов.
Данная реализация

public class TestBase {
clickTabButton(locator);```
выглядит довольно странно и особого профита не принесет.

спасибо, как обычно у меня в общем )

этого достаточно GitHub - SeleniumHQ/selenium-google-code-issue-archive: Archive, please see main selenium repo, чтобы освоить эту технику или надо что-то более глубокое почитать для блондинко?

Для Web в общем случае это утверждение не верное. Т.к. на разных страницах одинаковые на вид элементы могут быть реализованы по-разному. Следовательно, завернуть работу с ними в один метод (красиво и полезно) не получится. Бывают исключения, но в общем на это лучше не ориентироваться.

Лучше всего строить архитектуру фреймворка по-странично. Одна страница интерфейса - один класс. Паттерн PageObject, про который уже сказали выше как раз про это. И тогда:

  1. Страница предоставляет методы для работы со своими элементами: кнопками, текстовыми полями и т.д.

  2. А тесты уже работают со страницами, вызывая методы PageObject-ов:

    LoginPage.setLogin("admin");
    LoginPage.clickLoginButton();
    ...
    UserProfilePage.goTo();
    UserProfilePage.setFirstName("Diana");
    

    и т.д.

  3. Предыдущий шаг можно будет впоследствии ещё отрефакторить, чтобы тесты работали не со страницами, а с бизнес-функциями, например:

    UserProfile user = new UserProfile();
    user.setFirstName("Diana");
    
    UserService.updateProfile(user);
    

Здесь вся работа со страницами спрятана от теста за бизнес функцией updateProfile() и тогда код теста становится совсем лаконичным и человекочитаемым.

В этом направлении и двигайся. Начни с постигания дао PageObject-ов

2 лайка

К посту выше добавлю, вдруг, если понравится Thucydides, то посмотрите:

Thucydides проблема: Page Object Pattern и чекбоксы, селекты

Читай всё что найдешь пока не почувствуешь, что поняла :slight_smile: Потом пробуй делать сама и читай снова… и т.д.

Ну и в добавок к @ArtOfLife просто добавлю ссылку на видео по PageObject для начинающих

4 лайка

шикарное видео, и почему я до сих пор его не видел…