За пределами Page Object. ATDays 2013 Киев. Февраль 2013
-
Upload
dmytro-zharii -
Category
Documents
-
view
983 -
download
1
description
Transcript of За пределами Page Object. ATDays 2013 Киев. Февраль 2013
![Page 1: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/1.jpg)
atdays.com
За пределами
PageObject
Дмитрий Жарий
![Page 2: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/2.jpg)
atdays.com #atdays
Давайте познакомимся!
2
Дима Жарий
![Page 3: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/3.jpg)
atdays.com #atdays 3
Аджендиум… [OK] =================================================
1. Вам не нужен PageObject
2. Вам нужен PageObject
3. PageObject – это паттерн, шаблон… ИДЕЯ!
4. Статический PageObject
5. Динамический PageObject
6. За пределами:
• Паттерн «Цепочка ответственности»
и .Invoke()
• Интерфейс IHaveExpectedControls
• Наследование в тестах
![Page 4: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/4.jpg)
atdays.com #atdays
ВАМ ДЕЙСТВИТЕЛЬНО НУЖЕН
PAGE OBJECT?
4
![Page 5: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/5.jpg)
atdays.com #atdays
Нет. Если у вас парочка
несложных тестов
5
public void Wikipedia_Smart_Search_Test() { RemoteWebDriver driver = new InternetExplorerDriver(); driver.Navigate() .GoToUrl("http://en.wikipedia.org/wiki/Main_Page"); driver.FindElementByCssSelector(@"div#simpleSearch") .SendKeys("Webdriver Selenium"); Assert.AreEqual("http://en.wiki {...} Driver" , driver.Url); }
![Page 6: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/6.jpg)
atdays.com #atdays
Нет. Если у вас несколько
сложных тестов
6
![Page 7: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/7.jpg)
atdays.com #atdays
Ведь код можно улучшить
7
![Page 8: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/8.jpg)
atdays.com #atdays
Как улучшить?
8
Вынести часто используемый функционал
в общедоступные методы
Отформатировать код
Добавить комментарии driver.FindElement(By.XPath("//a[text()='Log On']")) .Click();
// Click on the Log On link. var logOnLink = driver.FindElement( By.XPath("//a[text()='Log On']")); logOnLink.Click();
![Page 9: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/9.jpg)
atdays.com #atdays
И, если у вас все под
контролем…
9
![Page 10: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/10.jpg)
atdays.com #atdays
ВАМ НЕ НУЖЕН PAGE OBJECT!
10
![Page 11: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/11.jpg)
atdays.com #atdays 11
var ddlMonthSelect = new SelectElement(driver.FindElementByName(@"EXPIRYDATE_MM")); var ddlYearSelect = new SelectElement(driver.FindElementByName(@"EXPIRYDATE_YY")); var txtSecurityCode = driver.FindElementByName(@"CVV"); var btnContinue = driver.FindElementById("btnSubmit"); ddlMonthSelect.SelectByText("05"); ddlYearSelect.SelectByText("15");
Прости, ня!
![Page 12: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/12.jpg)
atdays.com #atdays
Когда приходит Хаос…
12
"Тест-простыней" становится слишком много В коде не разобраться без пол-литру
На поддержку уходит уж слишком много времени Легче всё переписать заново
Начинаете ненавидеть разработчиков, которые вынесли div из span
![Page 13: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/13.jpg)
atdays.com #atdays
PageObject – он как книжная
полка
13
Pages
LoginPage
→ Login(name, passwd)
MainPage
→ LogOut()
→ GotoProjects()
→ GotoUserProfile()
→ Search(text)
![Page 14: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/14.jpg)
atdays.com #atdays
PAGE OBJECT – ОН ГИБКИЙ
14
![Page 15: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/15.jpg)
atdays.com #atdays
PageObject – это:
15
Концентрация
на языке задачи,
а не на языке решения
![Page 16: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/16.jpg)
atdays.com #atdays
PageObject – главная цель
16
Обеспечить хранение локаторов в отдельном классе
Обеспечить повторное использование локаторов и/или действий над страницей без дублирования кода
Обеспечить слой абстракции от «драйвера» так, чтобы в тестах не использовались физические элементы идентификации элементов управления приложением
![Page 17: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/17.jpg)
atdays.com #atdays
А выглядит всё вот так
17
MainPage
Create
Account
Page
Т
Е
С
Т
![Page 18: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/18.jpg)
atdays.com #atdays
Демо!
18
![Page 19: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/19.jpg)
atdays.com #atdays
ЧТО ЭТО БЫЛО? –
СТАТИЧЕСКИЙ PAGE OBJECT!
19
![Page 20: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/20.jpg)
atdays.com #atdays
Позитив 01: Тест стал
читабелен
20
public static RemoteWebDriver Driver { get { return WebBrowser.Driver; } }
[TestMethod] public void Donate_test_static() { MyPages.MainPage.Open(); MyPages.MainPage.GoToDonatePage(); MyPages.DonatePage.Donate_50_UAH_Using_Debit_Card(); MyPages.DonationPaymentsForm.FillDonationForm ( firstName : "Vasya", lastName : "Pupkin", securityCode : "555" ); // CUT
}
![Page 21: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/21.jpg)
atdays.com #atdays
Позитив 2: Удобная «точка
входа» в страницы
21
![Page 22: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/22.jpg)
atdays.com #atdays
Позитив 3: Driver стал доступен
отовсюду!
22
public static class WebBrowser { public static RemoteWebDriver _driver = null; public static RemoteWebDriver Driver { get { _driver = _driver ?? new InternetExplorerDriver(); return _driver; } } }
public static RemoteWebDriver Driver { get { return WebBrowser.Driver; } }
![Page 23: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/23.jpg)
atdays.com #atdays
И еще раз о позитиве
23
Теперь жизнь браузера (драйвера) контролирует класс WebBrowser.
Текущий драйвер доступен из любого участка кода
Любая страница доступна из MyPages.* Наш тест теперь помещается на один экран монитора
![Page 24: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/24.jpg)
atdays.com #atdays
Ограничения статического
класса в C#
24
class static class
Наследоваться можно нельзя
Породить много разных можно нельзя
Инициализировать параметрами через конструктор
можно нельзя
Завалить можно полностью нельзя. Очень живучие
Присвоить переменной можно нельзя
Передать как параметр другому методу можно нельзя
Реализовать интерфейс можно нельзя
Использовать статические методы можно можно
Использовать статические поля можно можно
Инициализировать при помощи Webdriver PageFactory
можно нельзя "из коробки", нужно написать свою фабрику
![Page 25: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/25.jpg)
atdays.com #atdays
ГИБКОСТЬ – ЭТО ВАЖНО.
PAGE OBJECT КАК OBJECT
25
![Page 26: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/26.jpg)
atdays.com #atdays
Тест не изменился! Спасибо,
MyPages
26
![Page 27: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/27.jpg)
atdays.com #atdays
Изменения в MyPages
27
public static class MyPages { public static MainPage MainPage { get { return new MainPage();} } public static DonatePage DonatePage { get { return new DonatePage(); } } }
![Page 28: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/28.jpg)
atdays.com #atdays
Новая структура проекта
Object Static
28
![Page 29: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/29.jpg)
atdays.com #atdays
AbstractPageBase
29
public abstract class AbstractPageBase { public RemoteWebDriver Driver { get { return WebBrowser.Driver; } } }
![Page 30: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/30.jpg)
atdays.com #atdays
PaymentResultPage
30
public class PaymentResultPage : AbstractPageBase { public void WaitUntilExists() { WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(30)); wait.Until(ExpectedConditions.TitleContains( @"Donate-error - Payments")); } public string GetResultHeaderText() { var lblFirstHeader = Driver. FindElementById(@"firstHeading"); return lblFirstHeader.Text; } }
![Page 31: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/31.jpg)
atdays.com #atdays
Changelog
31
Появился базовый класс
AbstractPageBase
Из MyPages.* можно по-прежнему
получить любую страницу Декларация страниц была вынесена из MyPages в отдельные файлы
Мы лишились ограничений статических
классов
ТЕПЕРЬ НАС НЕ ОСТАНОВИТЬ!
![Page 32: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/32.jpg)
atdays.com #atdays
Статический/Динамический –
разница в перспективах
32 Статический Динамический
![Page 33: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/33.jpg)
atdays.com #atdays
ПАТТЕРНЫ (РЕЦЕПТЫ)
И ИНТЕРФЕЙСЫ (РОЛИ)
33
![Page 34: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/34.jpg)
atdays.com #atdays
ЦЕПОЧКА ОТВЕТСТВЕННОСТИ
/CHAIN OF RESPONSIBILITY/
34
http://bash.im/quote/420885
xxx: тема письма в рабочей почте
" RE: FW: FW: RE: RE: FW: RE: СРОЧНО!!!!!!"
yyy: Вот это проблема структурных
организаций
![Page 35: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/35.jpg)
atdays.com #atdays
Chain of Responsibility
35
? ??
???
????
Цепочка ответственности
![Page 36: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/36.jpg)
atdays.com #atdays
Iinvokable
36
public interface IInvokable { void Invoke(); bool Exists(); }
Invoke – вызвать
Invokable – то, что можно вызвать
I invokable – Я вызываемый(-оя, -ое)!
![Page 37: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/37.jpg)
atdays.com #atdays
НужнаяPage.Invoke():
37
НужнаяPage.Invoke():
Если я уже Exists() – то вот она я!
Если я не Exists(), то я сделаю:
ПредыдущаяPage.Invoke()
Потом что-то нажму – вот она я!
Donation
Payments
Form
Donate
Page
![Page 38: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/38.jpg)
atdays.com #atdays
Что дает нам Iinvokable?
38
Любую страницу можно вызвать с
параметрами по умолчанию
var page = MyPages. PaymentResultErrorInvalidCreditCard; page.Invoke();
![Page 39: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/39.jpg)
atdays.com #atdays
Что дает нам Iinvokable?
39
Передать страницу как параметр метода
public void TestThatPageExists(IInvokable page) { page.Invoke(); Assert.IsTrue(page.Exists()); } [TestMethod] public void Test_PaymentResultErrorInvalidCreditCard() { TestThatPageExists( MyPages.PaymentResultErrnvalidCreditCard ); }
![Page 40: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/40.jpg)
atdays.com #atdays
Что дает нам Iinvokable?
40
Если нужная страница уже открыта (после
предыдущего теста ) – она будет использована
повторно
public void Invoke() { if (Exists() == false) { var mainPage = MyPages.MainPage; mainPage.Invoke(); mainPage.GoToDonatePage(); } }
![Page 41: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/41.jpg)
atdays.com #atdays
I HAVE EXPECTED CONTROLS
41
![Page 42: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/42.jpg)
atdays.com #atdays
Сышишь, а есть какиета
кантролы?
42
public interface IHaveExpectedControls : IInvokable { List<IWebElement> GetExpectedControls(); }
.Invoke()
.Exists()
.GetExpectedControls()
![Page 43: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/43.jpg)
atdays.com #atdays
Get Expected Controls
(PageObject)
43
public class DonatePage : AbstractPageBase, IHaveExpectedControls
{ [FindsBy(Using=@"input[name='amount'][value='50']", How = How.CssSelector)]
public IWebElement rbtnDonate50; [FindsBy(Using=@"input[value='Donate by credit/debit card']", How = How.CssSelector)]
public IWebElement btnMakeDonation; public List<IWebElement> GetExpectedControls() { return new List<IWebElement>() { rbtnDonate50, btnMakeDonation }; }
![Page 44: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/44.jpg)
atdays.com #atdays
Позволяет писать
универсальные тесты
44
public virtual IHaveExpectedControls CurrentPage { get { return null; } } [TestMethod] public void TestExpectedControls() { CurrentPage.Invoke(); var expectedControls = CurrentPage.GetExpectedControls(); foreach (var expectedControl in expectedControls) { Assert.IsTrue(expectedControl.Displayed); } }
![Page 45: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/45.jpg)
atdays.com #atdays
Авто-тесты для авто-тестов?
45
Легкие тесты, которые:
1. Открывают каждую страницу
2. Проверяет каждый важный
элемент страницы
Основной тест-набор
![Page 46: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/46.jpg)
atdays.com #atdays
Та да да дам!
46
![Page 47: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/47.jpg)
atdays.com #atdays
Спасибы:
47
За то, что доклад состоялся:
Спасибо Вам!
За Invoke() Виктору Линчевскому
Леониду Артемьеву
Помощь в подготовке доклада: Михаил Поляруш
Андрей Ребров
![Page 48: За пределами Page Object. ATDays 2013 Киев. Февраль 2013](https://reader034.fdocument.pub/reader034/viewer/2022042816/558bc39ed8b42ac74b8b4640/html5/thumbnails/48.jpg)
atdays.com #atdays
Я не прощаюсь, я говорю: до
свидания!
48
Дима Жарий