Geb на практиці
Я ось, скажімо, люблю, коли всю роботу за мене роблять роботи. Тому вважаю за необхідне всякі скрипти, inspections, дослідник орфографії і, зрозуміло, автоматичні тести. До речі, як вам такий тестик:
Мені здається, у таких тестів високий ступінь читабельності - неважливо навіть, який це мова. Можна за таким ось зразком написати ще кілька подібних же тестів, не маючи взагалі ніякого поняття про Geb, Groovy і про те, як це працює. Але для повного розуміння трохи заглибимося в основи.
Про Geb і Selenium
Хто в наші дні не чув про Selenium. Напевно, той, хто ще пороху не нюхав і до сих пір думає, що всі браузери однакові. Довго я про це поширюватися не буду, досить лише знати:
- Selenium дозволяє запускати автоматичні тести прямо в браузері, відтворюючи всілякі глюки і особливості.
- Можна робити ВСЕ те, що робить звичайний користувач, а саме набирати текст, скролл, рухати мишкою і т.п. При цьому уважно спостерігаючи за поведінкою сторінки в браузері.
Фактично Selenium - це повноцінний робот для тестування в умовах, максимально наближених до реальності. (Історично можна ще пригадати Rational Robot, який був заточений під Internet Explorer і мав досить мізерні можливості по взаємодії зі сторінкою.)
Сам Selenium надає кілька варіантів написання тестів:
Отже, Geb - це чергове засіб написання тестів, що використовує WebDriver і засноване на мові Groovy. Використовувати Geb всередині Groovy-скрипта можна за допомогою наступних чарівних слів:
Одна з особливостей Groovy (як і всіх динамічних мов) в тому, що його можна легко переробити в інший зовсім невпізнанним мову - під будь-які потреби.
У нашому випадку Geb надає мову управління браузером. Можна здійснювати всі, що вміє людський користувач:
- Переходити по URL
- заповнювати форми
- рухати мишкою
- Кликати по посиланню
- Взаємодіяти з різного роду popup-вікнами і фреймами.
Як бачимо, Geb дозволяє використовувати синтаксис, що нагадує jQuery (але не збігається з ним повністю). Це зручно для знаходження потрібних елементів в сторінці. Метод click () дозволяє клікати на DOM-елементи, операція <<— отправлять браузеру текст, и так далее.
Сторінки і модулі
і перейшли на сторінку gramant.com. Тепер можна цю сторінку «прочитати», тобто проаналізувати і знайти помилки. Так? Насправді ні. При попаданні браузера на сторінку може трапиться:
Ми думаємо, що знаходимося на одній сторінці, а опинилися на інший. Далі тести підуть неправильним шляхом. Тому дуже важливо розуміти, на якій логічній сторінці ми знаходимося.
Geb пропонує використовувати логічні сторінки (Page) і так звані модулі (Module). Спробуємо це проілюструвати так:
Навіщо взагалі потрібна така абстракція, як сторінка. Здавалося б, досить подивитися поточний URL і ми всі дізнаємося. Наприклад, так:
Але буває, що одна і та ж логічна сторінка може мати безліч різних URL і станів, причому не завжди правильно визначати сторінку за URL (який може непередбачувано змінитися). Можна це робити, наприклад, за назвою:
Можливі й інші варіанти визначення поточної сторінки; як бачимо, все це сильно залежить від програми. Іноді безліч різних URL відповідають одній і тій же сторінці; іноді по одному і тому ж URL в залежності від внутрішнього контексту може з'явитися кілька різних сторінок. У загальному випадку псевдо-властивість at містить логіку визначення того, чи знаходиться зараз браузер на даній сторінці.
Кілька слів про модулі. На діаграмі видно, що модуль - це частина сторінки (блок), причому є модулі, які присутні на кількох сторінках. Наприклад, пошуковий рядок Яндекса доступна як на портальної сторінці, так і над результатами пошуку. Сенс модулів - повторне використання тестирующего коду.
Модулі можна визначити, наприклад, так:
І потім використовувати їх таким чином:
Існує, зрозуміло, можливість, визначати багато примірників модуля всередині сторінки - це актуально для різного роду списків. Наприклад, результати пошуку - кожен результат можна оголосити модулем. Це робиться з використанням конструкції moduleList. на якій я зупинятися не буду.
AJAX і все, все, все
В теперішні часи всередині браузера може відбуватися безліч дивовижних речей:
- AJAX-запити
- анімація
- Drag Drop
- Popup-вікна різного виду
Тестувати такі штуки автоматично можна тільки за допомогою in-browser тестів. Geb пропонує кілька інструментів:
Можна також користуватися глобальними функціями:
Для емуляції мишачих подій зручно використовувати jQuery. Geb надає спеціальне властивість jQuery для такого роду викликів:
Цей рядок буде працювати тільки за умови, що на тестованої сторінці завантажена jQuery версії 1.4 і вище. Фактично такий код транслюється в js.exec ().
Умова очікування
Цей скрипт одержує embed code для ролика YouTube, натискаючи кілька кнопок і чекаючи завершення анімації.
Зрозуміло, вічно метод waitFor чекати не буде і після досягнення деякого часу очікування впаде, перервавши тест. За замовчуванням це 5 секунд.
Використання WebElement і Actions
Ми згадали про Drag Drop. На даний момент (версія 0.6.2) Geb не має зручної абстракції для здійснення таких операцій. Проте, завжди є можливість використовувати Selenium безпосередньо, звернувшись до примірника WebDriver (через browser.driver):
Geb всередині Grails
Для використання Geb в Grails зручно застосовувати плагін Spock. Я не буду довго розводитися про Spock Framework, інформації про нього досить. Spock зручніше стандартного JUnit насамперед тим, що дозволяє писати тести на своєму мета-мовою специфікацій (знову-таки на базі Groovy). Це виходить і коротше, і виразніше.
Кілька слів про налаштування Geb для Grails 1.3.x. Приклад такого проекту викладений тут. Потрібна секція в BuildConfig.groovy буде виглядати так:
Поточний gebVersion - 0.6.2, підставте потрібний.
Ми знаємо, що в Grails є два типи тестів - test / unit і test / integration. Spock додає ще й test / functional - «функціональні» тести.
Geb всередині функціональних тестів (специфікацій Spock) схожий на звичайний, але запускати браузер і конфігурувати драйвер всередині тесту не потрібно - все вже зроблено. Приклад простенької специфікації (припускаємо, що класи HomePage, LoginPage нами вже описані):
Звичайно, є ще файли настройки Geb, які визначають:
- Який браузер використовувати і з яким драйвером
- Різноманітні налаштування Geb (такі як таймаут).
У демонстраційному прикладі є приклад файлу GebConfig.groovy.
Начебто цього достатньо. набираємо:
і дивимося, як наш робот намагається щось там тестувати.
Швидко з'ясовується, що на Chrome і IE наші тести не працюють. Причина в тому, що реально з нуля і без підручних засобів можна запустити або HtmlUnit (який для тестування марний) або Firefox. Для Firefox автоматично створюється новий профіль, який «розширює» браузер для подальшого управління через FirefoxDriver. Так, Selenium / Geb чудово працює на Firefox, тому що саме для Firefox він спочатку і розроблявся.
Що стосується IE і Chrome, то з ними все трохи складніше. Загальну ситуацію можна зрозуміти з таблички:
Версії 6,7,8,9. Підтримує рівно один зразок навігатора.
Як бачимо, драйвер Chrome не підтримує Actions! Що досить неприємно.
Що ще офіційно підтримує Selenium (а, отже, Geb)?
- браузер iPhone
- браузер Android
Писати чи браузерні тести?
Принадність браузерних тестів в гарантованості поведінки на конкретному браузері.
Однак браузерні тести:
Найпростіша формула, що описує необхідність написання автоматичних тестів, може виглядати так:
Формула красива, але досить безглузда, так як заздалегідь оцінити трудомісткість підтримки і вартість ручного тестування ітерації дуже важко. Але ясно, що з ростом числа ітерацій думка автоматизувати тестування буде приходити вам у голову все частіше і частіше. На низьку швидкість виконання браузерних тестів можна не звертати багато уваги - це все одно швидше, ніж виконувати ручне тестування. Правда, формула не враховує того, що не вся ручна робота може бути автоматизована - спробуйте, скажімо, пояснити роботу, що означає «верстка поїхала».
Є також свої тонкощі в браузерному тестуванні. Наприклад, Selenium не завжди здатний самостійно визначити, чи доступний взагалі веб-сайт, на який зайшов браузер. Дійсно, в разі, скажімо, вирубування Інтернету браузер начебто щось показує. Але це не ваша очікувана сторінка, а внутрішнє повідомлення браузера в стилі «перевірте свої налаштування Інтернет». Всі ці ситуації вам доведеться самим визначати і включати в тестовий пакет. Крім цього, іноді доводиться пристосовувати додаток під автоматичні тести, йдучи на якісь компроміси.
Взагалі, це може звучати незвично, але автоматичний тест - це програма. Отже, іноді її розробку і підтримку можна доручити програмістам. Цей підхід нівелює суворий поділ праці між програмістом і тестувальником. В рамках налагодженої системи збирання та тестування частина застосовують принцип «сам зламав тест, сам і чини». Тобто, грубо кажучи, неважливо, хто тест написав - з моменту створення він стає спільною власністю і відповідальність за роботу тесту несуть як тестувальники, так і програмісти.