Как протестировать страницу интернет-магазина на Selenium. Дизайн.

Коллеги, добрый день!

Я начинающий автоматизатор, но уже написла свои первые тесты на Srlrnium c помощью Java и Page Object, думала чтоя неплохо поняла основные концепции. И вот недавно на собеседовании меня поставил в тупик следующий вопрос: как протестировать страницу интернет-магазина? Я где-то читала о том, что все товары нужно поместить в хэш-мап, ну и по мере необходимости оттуда вытягивать. Когда интервьюиер начал копать детали, я поняла что я на самом деле ничего не понимаю о том, как же лучше сделать дизайн для такого теста.

Чтобы не быть голословными, возьмем первый попавшийся интернет-магазин, я выбрала этот:

Допустим, в нашем тесте мы пробуем купить MacBook Pro 13 дюймов серебрянного цвета с процессором Core i5 и с наличием Touch Bar.

Согласно концепции Page Object, мы создаем страницу с описанием элементов страницы. В случае «обычной» страницы я бы просто переписала имеющиеся на странице контроллы в объекты WebElement и написала бы методы для управления ими. В случае же веб-магазина мы поместим все товары в хэш-мап, так? Поправьте если идея изначально неверная и нужо было действовать иначе.

Итак, у меня по сути 4 больших вопроса:

  1. Что является ключем в хаш-мап? Стринг показался мне совершенно неверной идеей так как у меня не получится идентифицировать товар по какому-то слову. Я подумала что можно создать отдельный объект, напимер Item. У объекта будут вполне конкретные атрибуты типа Model, Color, Processor, TouchBar. В данном случае мой тест сможет найти в хаш-мап вполне себе конкретный товар и попытаться его купить. Возник только вопрос, насколько идея создания дополнительных объектов, не Page Object, вписывается в фреймворк Page Object? Можно ли делать что-то подобное, либо это считается антипатерном?
  2. Что является значением, кторое мне вернет хаш-мап? WebElement зеленой кнопки Buy Now? Таким образом я протестирую переход на страницу с детальным описанием товара и возможностью его купить. Либо же WebElement картинки, кликнув на которую я также попаду на страницу с описанием товара и возможностью его купить? В этом магазине страницы после перехода разные, поэтому видимо нужно создавать два хаш-мап? И написать 2 теста для покупки? А если представить что оба WebElement вели бы на одну и ту же страницу (что лично я встречала в жизни), как лучше всего было бы сделать дизайн Page Object страницы?
  3. Что делать с линком “Be the first to write a review”. Конечно он не относится к нашему тесту покупки компьютера, но ведь каждому Item принадлежит и свой такой линк, значит еще один хаш-мап для линков с написанием ревью? И данный хаш-мап мы будем использовать уже при тестировании написания ревью.
  4. Вроде как с хаш-мапами на этой странице закончили? Получается, что для полного покрытия тестами, для КАЖДОГО контролла, принадлежащего товару, нужно создать по хаш-мап, куда будут помещены все товары со страницы итернет магазина. Как тогда инициализировать все хаш-мап (я имею ввиду добавить в пустой хаш-мап элементы), в конструкторе страницы? Получится конструктор невероятной длинны, некрасиво как-то…

Полно вопросов… Буду благодарна за советы, ссылки на видео-тьюториалы либо гитхаб подобных фреймворков.

А есть код посмотреть как реализовывать с помощью хеш-мап?

Да, конечно. Чтобы не перегружать, выложу только код самой страницы и тест. Если этого мало, могу выложить и все остальное.

public class MacbookProOverviewPage extends AbstractPage {
@FindBy(css=".model2016 div [class*='prod-40658075'] .button")
WebElement BuyNowButton_13Silveri5withTouch;

@FindBy (css= ".model2016 div [class*='prod-40658075'] .prod-img>a>img")
WebElement Image_13Silveri5withTouch;

@FindBy (css=".model2016 div[class*='prod-40658075'] .reviewLink>a")
WebElement ReviewLink_13Silveri5withTouch;

private HashMap<Item, WebElement> buyNowButtonMap = new HashMap<Item, WebElement>();

public MacbookProOverviewPage(WebDriver driver, WebDriverWait wait, Item item) {
	super(driver, wait);
	setBuyNowButtonMap(buyNowButtonMap, item);	
}

public HashMap<Item, WebElement> getBuyNowButtonMap() {
	return buyNowButtonMap;
}

public void setBuyNowButtonMap(HashMap<Item, WebElement> buyNowButtonMap, Item item) {
	this.buyNowButtonMap = buyNowButtonMap;
	buyNowButtonMap.put(item, BuyNowButton_13Silveri5withTouch);
}

public MacbookPro_13Silveri5withTouch_Page clickBuyNowButton(Item macbook) {
	this.getBuyNowButtonMap().get(macbook).click();
	return new MacbookPro_13Silveri5withTouch_Page(driver, wait);
}

}

И сам тест

public class BuyTest extends AbstractTest{

Item MacbookPro_13Silveri5withTouch = new Item("MacbookPro13", "Silver", "i5", true);

@Test
public void BuyTest() {
	MacbookProOverviewPage macbookProOverviewPage = new MacbookProOverviewPage(driver, wait, MacbookPro_13Silveri5withTouch);
	macbookProOverviewPage.wait(macbookProOverviewPage.getBuyNowButtonMap().get(MacbookPro_13Silveri5withTouch));
	macbookProOverviewPage.clickBuyNowButton(MacbookPro_13Silveri5withTouch);
}

}

[quote=“Katya_Kravchenka, post:1, topic:16506”]
Полно вопросов… [/quote]
И ответить на них полноценно вряд ли можно кратко.
Начните с простого:

  1. Забудьте про хеш-меп - он вам тут не нужен.
  2. Почитайте про D(ata)T(ransfer)O(object).
  3. Поменяйте слово Page на Screen в “Page Object” и посмотрите на те же HTML Elements от яндекс.

@vmaximv, спасибо за советы. Честно говоря, вопросов стало еще больше. Не могли бы вы прояснить следующее:

  1. Как DTO применяется в контексте тестов на селениуме? Из прочитанного мною, DTO применяют как а) альтернативу вебсервисам б) некий контейнер параметров в случае если необходимо написать метод с 4-5 и более входящими параметрами

  2. HTML Elements от яндекс безусловно полезная вещь, спасибо что поделились. Но я не вижу как их можно применить для описания страницы интернет-магазина. Все примеры яндекса сводятся к тому, что есть некая группа элементов, которая а) повторяется, б) используется вместе. Согласна, что каждому товара на странице веб-магазина принадлежат одинаковые элементы и их конечно можно вынести в отдельный блок, а потом на странице PageObject только использовать. Но! Условие б) ведь не выполняется. То есть я небуду использовать в одном тесте и линк Buy Now и линк Review Item, это не имеет смысла. Следовательно написать методы для блоков не получится и особо упростить страницу тоже. Или я что-то упустила?

Вот тут даже схожий с вашим пример описывающий DTO.

Ничего не напоминает ? :wink:

Вы выбрали какой то сложный интернет магазин для первого раза, имхо. Найдите что то суперпростое с каким то 1 типом товаров. А то закапаетесь в вариантах описания абстрактного товара.

@Artyom, спасибо за разъяснение. Согласна, созданный мною Item действительно напоминает DTO, в нем только атрибуты и никакой логики:

public class Item {
String model;
String color;
String processor;
boolean touchBar;

public Item(String model, String color, String processor, boolean touchBar) {
	this.model = model;
	this.color = color;
	this.processor = processor;
	this.touchBar = touchBar;		
}

}

Хорошо, с этим разобрались.

Но осознание того, что Item - это DTO, никак не помогает сделать дизайн PageObject. Интернет-магазин достаточно простой на мой взгляд, одни только макбуки разных цветов продают…

К сожалению, вопрос о том, каким образом сделать PageObject страницы, чтобы класс теста максимально просто находил нужный товар, для меня остается открытым.

так это как получается, если у нас категорий товара 150, то будет 150 item-ов? поскольку каждый айтем хранит уникальное состояние только для себя?

@bing278 ну для 100% покрытия тестами да, а как иначе? более того, за каждым объектом ведь стоят уникальные контроллы с локаторами на странице, мы же их все хотим протестировать.
Если знаете как это сделать проще/лучше - поделитесь, я буду рада узнать более оптимальный способ

Если закончились идеи тестов, музу ищем по ссылке:
https://www.exploit-db.com/webapps/

А что если нам описать класс покупки (абстрактный, поскольку он будет применим для любого товара), название товара будем брать из бд, локаторы будут универсальные, поиск по тексту будет производиться или по коду товара (не принципиально), ну как то так, просто смысл хранить эту(эти) мапы, а поддержка? это первое что пришло на ум

Спасибо за ссылку, но там ведь ничего нет о Selenium Webdriver_ тем более о задаче данного топика…

Не понимаю что вы хотите этим сказать.

и?

Это как? в селениуме все поиски тестируемых на WЕВ странице объектов производятся чезез CSS, Xpath, или по тэгам типа id, class etc.

Выложите пожалуйста код того, что предлагаете. Всего один конкретный тест покупки компьютера с использованием фреймворка Selenium Webdriver и PageObject.

По ссылке ошибки в веб приложениях, среди которых много магазинов. Из неё можно много тестов набрать для тестирования форм.

например локатор //div[contains(text(), 'название какого либо товара')] является универсальным, и он будет искать абсолютно любой товар (соответственно по имени), вам придется менять только текст в пейджах

под кодом я имел виду это prod-40658075 явно этот код тоже присутствует в бд (это альтернатива поиска по тексту)

3 лайка