Page Object паттерн сейчас требуется везде в компаниях ?

design-patterns
oop
page-object
Теги: #<Tag:0x00007fedb88d9e08> #<Tag:0x00007fedb88d9cc8> #<Tag:0x00007fedb88d9b60>

(Alex Alex) #1

Привет . Есть проблема . Я неплохо знаю селениум джава на процедурном уровне, но не понимаю как писать в стиле ООП. В компаниях везде используют ООП подход? Как мне понять page object паттерн ? Может кто-то на пальцах объяснит?


(Дмитрий Еремин) #2

Интернет на 90% состоит из порно и на 10% - из туториалов по селениуму
Если вы не нашли статью, которая доступно объясняет, как делать PO, ищите еще - она есть)
Ну и, к тому же, на ютубе очень много таких же курсов, где 1-2 урока объясняют, как все настроить и что, вообще можно, а потом пилят PO
Ну и, безусловно, понять паттерн будет легче, когда начнете увереннее себя чувствовать по части ООП. Тут лайфхаков нет: придется как следует почитать на эту тему хоть какой-нибудь учебник по джаве и попрактиковаться. С классами вы уже работаете, если пишете на Java. Осталось просто разобраться, что из всего этого - ООП
Удачи)


(Sergei Chipiga) #3

:smiley: :smiley: :smiley:


(Alex Alex) #4

Проблема в том что я именно поэтому и не стал программистом , что не понял ООП. Думал тестером аутомейшн смогу стать , но и тут ООП есть… вы можете мне тут онлайн шаг за шагом помочь реализовать этот паттерн на простом примере логина/регистрации?


(Yurij Litvin) #5

Вроде проще некуда описано: https://kreisfahrer.gitbooks.io/selenium-webdriver/content/page_object_pattern_arhitektura_testovogo_proekta/ispolzovanie_patterna_page_object.html


(Alex Alex) #6

Я читал эту статью . В теории понятно , но на практике не знаю как применить. Если я напишу код, вы сможете проверить тут и подсказать ?


(Дмитрий Еремин) #7

конечно. Помогать по существующему коду всегда легче. Особенно, если вопросы будут конкретными.


(Alex M) #8

Просто попробуй. Не нужно “если”. Когда начнешь писать код сам - начнешь понимать понемногу зачем это и что это.

Смеяться никто не будет. Все с чего-то начинают.
Как сказал Дмитрий Еремин - будет реально легче показать тебе в коде, а не говорить обобщенно.


(Alex Alex) #9

Вот я решил сделать простой пример, логинимся и разлогиниваемся с сайта (github.com).
Правильно ли я понимаю, что для этого мне надо 3 класса?

  1. LoginPage ( тот класс/страница, где мы логинимся на сайт)
  2. GithubPage ( тот класс/страница, когда мы уже зашли на сайт и разлогиниваемся)
  3. TestGithub ( это основной общий класс, где мы запускаем все написанные нами методы в 2 предыдущих классах).
    Если так, то я накидал в редакторе код для первого класса LoginPage.
  4. Все ли я сделал правильно?
  5. Что делать дальше?

Код LoginPage:


Class LoginPage{
	Webdriver driver;
	private By username = By.id(#username);
	private By password = By.id(#password);
	private By loginBtn = By.id(#loginbtn);
	
	//Конструктор - зачем он тут нужен?
	public LoginPage(Webdriver driver){
		this.driver = driver;
	}
	
	public void setUsername(String siteUsername){
		driver.findElement(username).sendKeys(siteUsername);
	}
	
	public void setPassword(String sitePassword){
		driver.findElement(password).sendKeys(sitePassword);
	}
	
	public void clickLoginBtn(){
		driver.findElement(loginBtn).click();
	}
	
	public void loginToWebsite(String siteUsername, String sitePassword){
		this.setUsername(siteUsername);
		this.setPassword(sitePassword);
		this.clickLoginBtn();
	}
}

(Alex Alex) #10

Второй класс судя по всему будет такой?
GithubPage

Class GithubPage{

	Webdriver driver;
	
	private By logoutBtn = By.id(#logoutbtn);
	
	public GithubPage(Webdriver driver){
		this.driver = driver;
	}
	
	public void clickToLogoutBtn(){
		driver.findElement(logoutbtn).click();
	}
	
	public void logoutFromWebsite(){
		this.clickToLogoutBtn();
	}
}

(Alex Alex) #11

И класс TestGithub. Тут я не дописал, потому что не понимаю что писать.

Class TestGithub{

	// зачем мы создаем эти объекты?
	Webdriver driver;
	LoginPage loginPageObject;
	GithubPage githubPageObject;
	
	@BeforeTest
	public static void SetUp(){
		driver = new ChromeDriver;
		driver.get("http://github.com");
	}
	
	@Test
	public void loginLogoutTest(){
		// Что тут писать не особо понял...
	}
	
}

(Alex M) #12

в принципе правильно, да, для каждой страницы нужно прописать ее локаторы и действия над локаторами.
Страницы:

  1. Лендинг пейдж откуда ты переходишь на Логин пейдж
    Локаторы и действия над локаторами (например, кнопка Sign In и клик по ней)
  2. Сама страница Логина
    Локаторы и действия над локаторами (например, заполнить поле имейл, кликнуть Сайн Ин)
  3. Страница после логина, где ты проверишь, что ты действительно залогинился
    Локаторы и действия над локаторами (например, что есть твое аватар в хидере)
  4. Класс с тестом (твой TestGithub), где ты будешь собирать уже те методы
    То есть, те действия, которые описал в 3 классах уже собираются в последовательные действия (шаги) и проверки для твоего теста.

В 4 классе тебе нужно создать инстансы Пейдж Обджектов (те 3 класса) для того, чтобы мочь обратиться к методам тех страниц в тестовом методе 4го класса.

Немного закручено. но, надеюсь, понятно)
Написал бы код, но я Джаву и Селением уже давно не тыкал - могу ошибиться, но могу дать примеры с Kotlin+Selenide.

P.S.
В TestGitHub классе
в теле метода loginLogoutTest
мы можем вызвать методы класса GithubPage по githubPageObject.clickToLogoutBtn()
или методы класса LoginPage по loginPageObject.setUsername
и таким образом собираем шаг за шагом, метод за методом уже сам тест.

Как-то так, вроде бы)


(Alex Alex) #13

Спасибо, я сейчас попробую уже конкретно этот пример реализовать.
А зачем в каждом классе писать конструктор и вызывать Webdriver driver?


(Alex Alex) #14

И что самое страшное для меня, я не понимаю вот такую штуку с методами
Когда надо писать скажем
public void NameMethod(){}

Когда надо писать
public String NameMethod(){}

Когда надо писать
public ClassName NameMethod(){}

И второй момент я не понимаю что такое RETURN и что именно и когда надо возвращать.
Вот в этом запара. То есть если бы писать можно было всегда методы типа VOID, то и не было бы проблемы … а так я не знаю когда какой тип писать


#15

Да у вас проблемы с джавой а не с ООП.
Return что-то возвращает, т.е результатом выполнения этого метода будет то что находится в return
т.е
public Integer sum (int one, int two){
return one+two;
}
результатом выполнения данного метода будет сумма переданых аргументов.
int summaDvohChisel = sum (2,3);


(Alex Alex) #16

а можно всегда ставить VOID и не париться? И ничего не возвращать. Пример ваш, только с VOID

public void sum(int one, int two){
int sum = one + two;
System.out.println(sum);
}

и всё, и не надо никаких непонятных ретурнов, не?

Ну и также вызвать

sum(2, 3);

#17

можно, ну выведет в консоль допустим 5 и мы ничего с ним делать не можем кроме того что оно в консоли отображается.
А если нам нужно
int abc = sum(2,3)/5 ?
и это самый примитивный пример.
на одних только воидах далеко не выедешь даже на том же Page Object что бы делать chained тесты нужно возвращать экземпляр или текущей страницы или страницы на которую мы перешли после действия прим.:
OrderConfirmedPage = new Homepage().clickProductsButton().selectProduct().clickAddToCart().fillShippingAddress.clickCheckoutButton();

Без этого код растянется на 10 никому не нужных строк.


(Alex Alex) #18

я сейчас сделал тест по патерну Page Object - заходим на гитхаб.ком - кликаем на Лог Ин - переходим на логин страницу - логинимся - затем разлогиниваемся. Я написал где-то всего 5 методов на все 3 класса и все они VOID. Можете привести для моего примера такой тест, при котором метод VOID не подойдет? Конкретно в примере вот с гитхабом.


#19

Вот как будет выглядеть тест в твоём случае

@Test
public void loginLogoutTest(){
LoginPage lp = new LoginPage(driver);
lp.loginToWebsite("login","pass");
GithubPage gp = new GithubPage(driver);
gp.logoutFromWebsite();
}

А вот так в моём

public void loginLogoutTest(){
GitHubPage = new LoginPage().logintoWebSite("login","pass").logoutFrowWebsite();
}

#20

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

Скажу так что без понимания работы return даже интерном никуда не возьмут.