Автоматизація тестування з застосуванням Ruby і WATIR

image
Шановні відвідувачі ресурсу habrahabr.ru! Ми хочемо познайомити Вас зі статтею Джеремі Суареса (Jeremy Suarez), інженера по автоматизації тестування. Якщо Ви плануєте організувати автоматизоване тестування на своєму проекті з застосуванням мови Ruby і WATIR — ця стаття Вам доведеться як не можна до речі. Джеремі описує все простою мовою, на елементарних прикладах. Після прочитання статті у Вас сформується чітке розуміння процесу — від його початкових кроків, до завершального етапу.

Перш ніж ми перейдемо безпосередньо до матеріалу, хотілося б кілька слів присвятити авторові. Джеремі має багатий досвід роботи у сфері тестування. На своїх численних проектах він обіймав різні ролі — від розробника, до тестувальника і менеджера проекту. Зараз він працює в компанії ThoughtWorks.

Отже, приступимо!

Цільова аудиторія
Цей матеріал буде корисний насамперед інженерам-тестувальника, які планують створювати автоматизовані тестові сценарії, або для тих, хто збирається підтримувати готовий фреймворк. Передбачається, що читач володіє базовими знаннями синтаксису Ruby і знайомий з основними принципами розробки web-додатків (такі терміни як «посилання», «форма», «JavaScript» не призводять до панічної атаки).

Ruby — порівняно простий в освоєнні мову. Якщо у Вас вже є певний досвід написання коду на Python, C++, Java або C, Ви досить швидко освоїте його.

Передумови та обмеження
Тут описані деякі необхідні умови використання WATIR для тестування web-додатків. Мабуть, основним з них є те, що модуль працює тільки з IE 5.5 і нижче. На жаль, він не призначений для роботи з Netscape, Opera, Firefox або будь-яким іншим браузером. Це означає, що крос-браузерне тестування з використанням WATIR неможливо. Друга важлива деталь — у WATIR немає власного рекордера. За великим рахунком, WATIR це бібліотека методів і об'єктів IE, які можна використовувати при написанні скриптів вручну. І нарешті, третє — у WATIR немає коштів для ідентифікації об'єктів, розташованих на сторінці, а також їх типів і доступних методів. Він надає методи для збору всіх посилань, зображень, форм і т. д. Тому процес розробки сценарію найчастіше проходить за методом проб і помилок, що, до речі, необов'язково погано.

Підготовка
Будь-процес написання автоматизованих тестових скриптів обов'язково передує процес підготовки. Самим важливим моментом в цьому випадку, мабуть, є те, що всі авто-тести, по суті, логічно витікають з вже готових, ручних сценаріїв тестування. Велика частина зусиль на розробку тестового фреймворку витрачається марно через некоректно написаних ручних тестів. Важливо розуміти — це основний момент, у подальшій підтримці і ручного і автоматизованого тестування. Необхідно бачити повну картину взаємодії бізнес-процесів, реалізованих за допомогою програми і підходити до їх опису охоплюючи весь скоуп (scope) завдань.

Розуміння специфіки досліджуваного програми
Збір функціональних вимог (якщо такі є)
Перед тим, як переходити безпосередньо до дизайну ручних або авто — тестів, необхідно зрозуміти, що з себе представляє Ваш додаток. Найпростіший спосіб — ознайомитися з вимогами до розробки. В наш час, документування вимог поширене практично повсюдно. А якщо є чітко сформульовані, повні і несуперечливі вимоги — це вже хороша стартова точка.

Опитування експертів
На додаток до вивчення функціональних вимог, або, в тому випадку, якщо їх немає, інформація може бути отримана безпосередньо від розробників продукту, а також кінцевих користувачів. Зазвичай в цьому процесі також можуть приймати участь архітектори, бізнес-аналітики і т. д. Важливо щоб в обговоренні брали участь якомога більше експертів з різних галузей, оскільки у розробників зазвичай своє уявлення про те, як має працювати додаток. І як правило, їх точка зору відрізняється від очікування клієнта.

Представлення бізнес-процесу через тест-кейси
Всі активності тестування, будь то ручне або автоматизоване, повинні бути засновані на детальних покрокових тестових сценаріїв. Без цього — стає проблематично відслідковувати прогрес тестування, а також відсоток покриття коду та інші метрики. Неправильно думати, що авто-тести — самі собі документація. Вони постійно змінюються, редагуються. Такий підхід призводить до великих тимчасових витрат і мультиплікації помилок.

Створення процесу підготовки даних
Багато програми в своїй роботі використовують або створюють деякі дані. В цілях тестування, як ручного, так і автоматизованого, стан даних у системі має бути однаковим від циклу до циклу. В залежності від того, що конкретно в даному випадку програма повинна робити — збирати, створювати або і те, і інше — повинні бути приготовані скрипти підготовки даних, а також скрипти очищення. Тести з підготовки та очищення даних слід оформити також, як і звичайні сценарії і використовувати як передумови останніх.

Визначення кейсів, придатних для автоматизації
Як свідчить відомий рекламний слоган: «Не всі йогурти однаково корисні». Теж саме відноситься і до тест-кейсів. Не всі з них слід автоматизувати. Тільки самі прості і часто повторювані є хорошими кандидатами. Почніть з кейсів, які працюють з UI, потім зверніть увагу на ті, в ході яких часто доводиться створювати та видаляти дані. Зрештою, спробуйте створити набір сценаріїв, що покривають найбільш важливі функціональні сегменти (найбільш часто використовувані функції).

Створення фреймворку автоматизованих сценаріїв
Як тільки у вас з'явиться чітке бачення, що конкретно потрібно тестувати, після того, як Ви задокументируете необхідні функції як покрокові кейси — ось тоді можна сміливо починати розробку самих скриптів авто-тестів. Скопіюйте свій ручний тест-кейс в порожній файл Ruby-скрипта. Закоментуйте кроки сценарію і розділіть їх на окремі ділянки. При поділі можна також дотримуватися принципу — створення даних в одному місці, використання — в іншому. Якщо в процесі роботи скрипта були згенеровані деякі дані, але сам кейс з якоїсь причини не дійшов до кінця — розумніше буде видалити ці дані і спробувати відновити скрипт.

Реалізація
У загальному випадку, реалізація процесу автоматизації сценарію тестування при використанні Ruby і WATIR зводиться до декількох простих кроків:
• Тест-кейс обраний і може бути запрограмований з допомогою набору функцій
• Ініціалізація об'єкта IE або з'єднання з існуючим вікном браузера
• Перехід з початкової посиланням програми
• Збір всіх посилань, зображень, форм необхідних для подальших дій
• Зібраної інформації виходить ім'я посилання, інформація про формою, ім'я картинки і т. д.
• Виконання дій над посиланням, формою, зображенням
• Повтор 3-6 кроків до тих пір, поки це необхідно. В кінці кожного кроку повинна бути перевірка, що вироблене дія закінчилася успішно.

Для досягнення максимальної ефективності, вкрай важливо супроводжувати кожен крок перевіркою. Якщо така перевірка не виконується — можна — можна знімати скріншот, копіювати логи, ну або принаймні, видавати зрозуміле повідомлення про помилку. Інакше ви ризикуєте отримати щось на зразок «Посилання не знайдено» або «Форма ххх недоступна».

Тільки від розробника скрипта залежить наскільки інформативним буде повідомлення про помилку, якщо щось пішло не так. Скрипти низької якості доведеться проганяти вручну щоб зрозуміти, що ж все таки сталося, а той час як коректно складений скрипт в змозі сам видати всю необхідну інформацію про збій.

Технічні аспекти реалізації
Ініціалізація об'єкта IE
Почніть зі створення нового об'єкта IE браузера або з'єднайтесь з вже існуючих.

$ie = IE.new()

Або

$ie = IE.attach ( :title, "...")

Перехід по стартовій посиланням

Починайте тестування програми переходом по заданій посиланням. Всі кейси починаються саме з цього. А іноді буває необхідно переходити за посиланнями в процесі виконання самого сценарію.

$ie.goto (“http://....")

Верифікація контенту

Найлегший шлях перевірки вмісту за допомогою команди assert. Переконайтеся, що форма існує, якась кнопка доступна, сторінка містить деякий текст і так далі… В Ruby немає циклу TRY, з цієї причини ми використовуємо ключове слово rescue.

begin
assert ($ie.pageContainsText(«Logged out Successfully») )
assert ($ie.form(:name, «Login»).exists )
$log.info («Test step 5 passed!»)
rescue
$log.error («Test step 5 failed»)
$log.info (“Error text was: “ ie.text() )
end

Збір необхідних посилань, зображень, форм

В процесі написання скрипта не завжди буває просто визначити точне найменування посилання або картинки, формат URL, назви полів і т. д. В таких випадках можна вивантажити дамп в лог-файл або на екран. Ця інформація буде корисна при створенні тесту або його налагодження, але її слід відключити в кінцевій версії кейса. Вихідні дані також можна виводити файли і стандартні пристрої виводу.

$log.info (), $log.error (), $log.warning () all output to the log4j log file.

Показати всі посилання:

puts $ie.show_links()

Показати всі форми:

puts $ie.show_forms()

Показати всі зображення:

puts $ie.show_images()

Показати всі об'єкти:

puts $ie.show_all_objects()

Показати всю сторінку цілком з усіма фреймами:

puts $ie.html()

Клік по посиланню

Активація посилання може бути проведена через її ім'я або безпосередній URL. При роботі з JavaScript посилання можна активувати тільки по URL, або якщо це посилання-картинка, по тегу її зображення (src, tag image). Метод click — один із стандартних методів WATIR для активації посилання.

$ie.link (:text, «Portfolio»).click

Якщо текст посилання може з часом змінитися, а її місце розташування — ні, тоді надійніше буде використовувати індекс посилання (використовуйте $ie.show_links() для пошуку індексів різних посилань):
$ie.link (:index, 20).click

У разі використання JavaScript, може бути використаний URL (або тег href):
$ie.link (:url, /javascript:deleteClient\(\d, .*/).click

Зауважте — URL слід закодувати (прогалини виражаються як %20 і т. д.). Можна вдаватися до допомоги регулярних виразів, як у прикладі вище.

Клік по зображенню
Клік по зображенню мало чим відрізняється від кліка по посиланню, за винятком наявності додаткових тегів scr і alt.
$ie.image (:name, “login.gif").click

Надсилання форми
Заповнення і надсилання форми, ймовірно, найбільш важкий крок виконується на етапі навігації по сайту. Для цього вам необхідно знати найменування всіх текстових полів, списків вибору або будь-яких інших елементів, присутніх на формі. Використовуйте ie.show_all_objects() для цих цілей.
$ie.textField(:name, «username»).set(«testuser»)
$ie.textField(:name, «password»).set(«testpass»)

Відправлення здійснюється «кліком» по відповідному об'єкту:
$ie.button(:value, «Login»).click

Невеликий екскурс по загальним об'єктів
Робота з спливаючими вікнами

Дії
new, back, forward, send_keys, goto, close, refresh, minimize, maximize, restore

$ie.back()
$ie.forwards()
$ie.send_keys("{TAB}{TAB}{ENTER}")
$ie.close
$ie.goto(“http://www.google.com")
$ie = IE.new()

Опції відображення
showFrames, show_frames, showForms, show_forms, showImages, show_images, showActive, show_active, showLinks, show_links, showAllObjects, show_all_objects, show_tables, buttons, show_spans, show_labels

$ie.show_tables
$ie.buttons.each {|m| puts m}

Успадковані об'єкти
frame, textField, span, row, selectBox, radio, select_list, text_field,
checkBox, button, checkbox, link, cell, form, table

$ie.frame(:index, 1)
$ie.textField(:name, «q»).set(«Test»)
$ie.button(:value, «ОК»).click
$ie.link(:text, «Happy link»).click
$ie.select_list(:name, «Day»).select_value(«today»)

Списки об'єктів
checkboxes, labels, images, spans, radios, select_lists, text_fields, buttons, tables, links

$ie.checkboxes.each {|m| puts m}
$ie.radios.each {|m| puts m}
$ie.links.each {|m| puts m}

Перевірки
getText, text, getStatus, status, getHTML, html, pageContainsText, contains_text, title:

if ($ie.text.match(«Hallo») != nil)
puts 'Passed!'
else
puts «Failed!'
$ie.contains_text(»Google")
Returns: True

Інші функції
getImage, getIE, enable_spinner, set_fast_speed, enable_spinner=, wait, popup, down_load_time, getLink, set_slow_speed, getTablePart, focus, url

Текстові поля
Опис
text name=question id= value= alt= src=

Об'єкти
textField, text_field

Методи розпізнавання
$ie.show_all_objects
$ie.show_active
$ie.textfields.each { |textfield| puts textfield}

Інші методи
value, value=, clear, click, send, set, enabled?, flash, html, append, getContents, focus, verify_contains

Найбільш використовувані методи
value, set, append, verify_contains.

Приклади
$ie.textField(:name, «q»).value=«Sam»
$ie.textField(:name, «q»).append(«I am»)
$ie.textField(:name, «q»).value
Returns: «I am Sam»
$ie.textField(:name, «q»).getContents
Returns: «I am Sam»
$ie.textField(:name, «q»).set(«Happy»)
$ie.textField(:name, «q»).verify_contains(«app»)
Returns: true

Кнопки
Опис
submit name=btnG id= value=Google Search alt= src=

Об'єкти
Button

Способи розпізнавання
$ie.show_all_objects
$ie.show_active
$ie.buttons.each { |button| puts button }

Інші методи
value, display, click, send, enabled?, flash, html, disabled, freeze, focus

Найбільш використовувані методи
Click

Приклади
$ie.button(:name, «btnG»).click
$ie.button(:name, «btnG»).value
Returns: «Google Search»

Посилання
Опис
" name= id= innerText=Business Solutions href=http://www.google.com/services/"

Об'єкти
Link

Методи розпізнавання
$ie.show_links
$ie.show_active
$ie.links.each { |link| puts link }

Інші методи
value, title, click, link_has_image, enabled?, flash, html, href src, text, focus, name, innerText, equal?

Найбільш використовувані методи
Click

Приклади
$ie.link(:text, «Business Solutions»).click
$ie.link(:text, «Business Solutions»).enabled?
Returns: true
$ie.link(:text, «Business Solutions»).link_has_image
Returns: false

Нотатки: посилання повертається без типу, якщо застосовуються методи show_active або show_all_objects.

Списки вибору
Опис
select-one name=logonForm:_idJsp15:0:Question id=logonForm:_idJsp15:0:Question value=What is your cat's name?

Об'єкти
select_list

Методи розпізнавання
$ie.show_all_objects
$ie.show_active

Інші методи
option, select, value, getSelectedItems, click, enabled?, flash, select_item_in_select_list, html, getAllContents, select_value, clearSelection

Найбільш використовувані методи
select, getSelectedItems, getAllContents, select_value, clearSelection

Приклади
$ie.select_list(:name, /Question/).value
Returns: «What is your cat's name?»
$ie.select_list(:name, /Question/).getAllContents
Returns array: [«What is your favorite color?», «What is your cat's name?»]
$ie.select_list(:name, /Question/).select_value («What is your cat's name?»)

Чекбокси
Опис
checkbox name=option1 id= value=Milk alt= src=

Об'єкти
checkbox
checkBox

Методи розпізнавання
$ie.show_all_objects
$ie.show_active
$ie.checkboxes.each {|checkbox| puts checkbox}

Інші методи
value, clear, click, set, enabled?, checked?, flash, html, ісеть?, getState

Найбільш використовувані методи
click, set, clear, checked?

Приклади
$ie.checkbox(:name, «Milk»).set
$ie.checkbox(:name, «Milk»).ісеть?
Returns: true
$ie.checkbox(:name, «Milk»).click
$ie.checkbox(:name, «Milk»).ісеть?
Returns: false
$ie.checkbox(:name, «Milk»).clear
$ie.checkbox(:name, «Milk»).ісеть?
Returns: false

Радіо-баттони
Опис
radio name=group1 id= value=Butter alt= src=

Об'єкти
Radio

Методи розпізнавання
$ie.show_all_objects
$ie.show_active
$ie.radios.each { |radio| puts radio }

Інші методи
value, clear, click, set, enabled?, checked?, html, ісеть?, getState

Найбільш використовувані методи
set, checked? (clear, carefully)

Приклади
$ie.radio(:value, «Butter»). Set
$ie.radio(:value, «Butter»).ісеть?
Returns: true

Примітка: метод Clear для радіо-кнопок краще не використовувати. Скинути радіо-кнопку краще натиснувши іншу
$ie.radio(:value, «Butter»). Clear

Фрейми (вони ж шари)
Опис
HTML Document name=message id= src=frameshop-intro.html

Об'єкти
Frame

Методи розпізнавання
$ie.show_all_objects
$ie.show_frames

Інші методи
Примітка: кадр веде себе як звичайна IE вікно. До нього можна звертатися по імені (прізвища), а також за індексом і зазвичай для звернення до нього створюють окрему змінну. Також часто кадри бувають вкладені в інші фрейми

Найбільш використовувані методи
Приклади
$f1 = $ie.frame(:name, «message»)
$f2 = $ie.frame(:index, 1)
$f1.show_all_objects
Останній рядок поверне всі об'єкти кадру, як звичайний ie об'єкт.

Технічні прийоми
Обробка спливаючого вікна
Завдяки поширеною схемою перевірок на стороні клієнта силами JavaScript та інших технологій, спливаючі вікна зустрічаються досить часто в тестуванні web-додатків.

Вони діляться на два типи: генеруються браузером IE і генеруються самим додатком.

IE зазвичай генерує спливаючі вікна, які з'являються лише один раз. Взяти хоча б попереджувала вікно Windows, що з'являється при спробі передати незашифровані дані, відправці форми або питання про запам'ятовування пароля. Рекомендується блокувати показ таких вікон у налаштуваннях IE і не обробляти їх в скрипті. JavaScript і ActiveX формують свої вікна, що вимагають від користувача підтвердити ту чи іншу дію, що відображають некоректні дані і т. д. IE не сприймає сторінку повністю завантаженої, до тих пір поки javascript діалог закрито не буде, тому і скрипт на Ruby не завершить свою роботу поки діалог закрито не буде.

Це може спровокувати проблему, оскільки для закриття вікна потрібно щоб відпрацював попередній крок, але він не може бути виконаний через діалогового вікна.

Для запобігання подібної ситуації рекомендується будь-які дії, які можуть спровокувати появу javascript спливаючого вікна, виконувати в окремому потоці. Це дозволить основному скрипту продовжити роботу, поки інший потік очікує закриття вікна.
Thread

Клік по кнопці підтвердження для закриття діалогу:
Clicker=WinClicker.new
Clicker.clickJavaScriptDialog («OK»)

Приховані кадри
Іноді, хоча функція show_frames і повертає 0, багато або навіть усі кадри на сторінці можуть бути частиною прихованого кадру. Якщо ви зіткнулися з такою ситуацією, за якої сторінка візуально містить об'єкти, але повертає порожній список, перевірте, чи не лежать вони в прихованому фреймі. Використовуйте наступну команду:
$ie.frame (:index, 1)…
Це дозволить звернутися до фреймах за індексом. Головний кадр має індекс 0, другий за рахунком, відповідно 1.

Інтерактивна розробка скриптів
Після того як ви звикнете до процесу написання скриптів на Ruby і WATIR, ви, ймовірно, знайдете його дуже виснажливим і час-витратним з-за відсутності власного рекордера. Одним із способів розігнати сумну тугу — час від часу застосовувати вбудований інтерпретатор ruby.

Інтерпретатор люб'язно надає вам можливість налагодження скрипта в режимі рядок за рядком у браузері. Ви можете застосовувати обговорювані вище методи, такі як show_links, show_all_objects для розпізнавання об'єктів на сторінці відображається, замість того щоб кожен раз запускати скрипт з початку.

Альтернативою може служити інтерактивна функція show_active_method. Вона застосовується для розпізнавання об'єкта, що знаходиться у фокусі в даний момент.
puts $ie.show_active()

Поради та хитрості
Вбудована підстановка
Назвіть змінної todaysDate значення поточної дати у форматі месяцденьгод (04212006)
$todaysDate = Time.now.strftime("%m -% d%Y")
Замініть дату в рядку на значення поточної дати
pimsSQL «delete from blotter_funds where name ='#_1' and prime_broker ='Bobby Brown'»
Або те ж саме, тільки використовуючи конкатенацию рядків
pimsSQL «delete from blotter_funds where name ='» + $todaysDate + "_1' and prime_broker ='Bobby Brown'"

Посилання на оригінал статті:
www.thoughtworks.com/insights/blog/creating-automated-test-scripts-ruby-and-watir

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.