UI Automation Patterns: "Sleep" Pattern

7,962 views
8,190 views

Published on

2 Comments
4 Likes
Statistics
Notes
No Downloads
Views
Total views
7,962
On SlideShare
0
From Embeds
0
Number of Embeds
3,876
Actions
Shares
0
Downloads
17
Comments
2
Likes
4
Embeds 0
No embeds

No notes for slide

UI Automation Patterns: "Sleep" Pattern

  1. 1. МОТИВАЦИЯ • Ваши автотесты постоянно валятся без видимых причин • Ваше приложение постоянно что-то подгружает втихаря • Ваше приложение не ожидает, что по нему будут слишком уж быстро кликать • Ваши автотесты проходят настолько быстро, что вы не успеваете попить кофе и хорошенько побраузать
  2. 2. ПРИМЕНИМОСТЬ Используйте паттерн «Сон», чтобы: • Подождать, пока какой-либо элемент появится на странице • Подождать, пока элемент исчезнет • Подождать, пока у элемента изменится какой-нибудь атрибут • Подождать на случай, если элемент может появиться, а может и нет • Подождать, потому что иначе приложение тупо рухнет • Просто подождать
  3. 3. СТРУКТУРА
  4. 4. УЧАСТНИКИ • SleepService – «сервис сна»: - определяет операцию sleep(), которая позволяет осуществить процедуру ожидания. Альтернативные наименования: pause(), wait() и т.п.
  5. 5. ОТНОШЕНИЯ SleepService, как правило, не имеет смысла выделять в отдельный класс. Вполне достаточно будет добавить его функциональность в один или несколько из уже существующих утилитных классов (возможно даже, с применением интерфейса или абстрактного класса CanSleep). Клиенты получают доступ к процедуре сна через вызов метод sleep().
  6. 6. РЕЗУЛЬТАТЫ • Легко добавить ожидание в любой точке кода • Любой компонент может при необходимости приостановить свое выполнение • Вызываемые автотестом методы исполняются обстоятельно и без спешки • Глядя на исполняющийся тест, можно по крайней мере понимать, что он делает, и при этом успевать заниматься прочими активностями • Общее время выполнения тестовой сюиты незначительно увеличивается за счет повышения надежности тестов
  7. 7. РЕАЛИЗАЦИЯ При реализации паттерна «Сон» необходимо рассмотреть следующие вопросы: • Сон должен блокировать выполнение теста • Время сна должно быть можно конфигурировать • Но должно быть можно инициировать сон и просто так, не заморачиваясь на таймаутах • Процедура сна должна быть масштабируемой • В случае, если во время сна что-то пошло не так, об этом надо куда-то сообщить • Но в некоторых случаях можно особо из-за этого не напрягаться
  8. 8. Простейшая реализация: public static void sleep(long timeout) { try { Thread.sleep(timeout); } catch (InterruptedException e) { e.printStackTrace(); } } Плюсы: просто и элегантно. Минусы: может засорять лог стектрейсами. Все равно никто не знает, что с ними делать. ПРИМЕРЫ КОДА
  9. 9. Улучшенная реализация: public static void sleep(long timeout) { try { Thread.sleep(timeout); } catch (InterruptedException e) { } } Плюсы: еще проще и элегантнее. Минусы: отсутствуют. ПРИМЕРЫ КОДА
  10. 10. ПРИМЕРЫ КОДА Продвинутая реализация с генерацией исключения: public static void sleep(long timeout) { try { Thread.sleep(timeout); } catch (InterruptedException e) { throw new RuntimeException(e.getMessage()); } } Плюсы: показывает, что вы не какие-нибудь там и умеете генерировать исключения. Обратите внимание, блок throws не требуется, так как это RuntimeException! Минусы: исключение нужно где-то как-то обработать.
  11. 11. ПРИМЕРЫ КОДА Продвинутая реализация с логированием предупреждения: public static void sleep(long timeout) { try { Thread.sleep(timeout); } catch (InterruptedException e) { LOGGER.warn("sleep() method was interrupted.", e); } } Плюсы: обработка исключения на более высоком уровне больше не требуется! Минусы: нужно инициализировать логгер. Засоряет лог предупреждениями, которые все равно никто не читает.
  12. 12. ПРИМЕРЫ КОДА Продвинутая реализация с таймаутом по умолчанию: private static final long DEFAULT_TIMEOUT = 15000; public static void sleep() { sleep(DEFAULT_TIMEOUT); } Плюсы: не надо думать о величине таймаута. Минусы: отсутствуют.
  13. 13. МАСШТАБИРУЕМОСТЬ Иногда необходимо выполнить ожидание в течение нестандартного отрезка времени. Как же сделать, чтобы процедура сна была масштабируемой? public void clientMethod() { … SleepService.sleep(sleepTime * 8); … } Это решение в лоб, очевидно, не годится, так как неприменимо для случая вызова метода sleep() без параметров. Как же быть?
  14. 14. МАСШТАБИРУЕМОСТЬ Все очень просто! public void clientMethod() { … SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); SleepService.sleep(sleepTime); … }
  15. 15. АЛЬТЕРНАТИВЫ Рассмотрим другие, неправильные, альтернативы решения проблемы: • [Решение] Реализовать процедуру «поллинга», т.е. опроса элементов в цикле на предмет достижения требуемого условия. • [Ответ] Но это же неэффективно! Вместо того, чтобы спокойно поспать, автотест должен постоянно обрабатывать какие-то инструкции, делать запросы, анализировать результаты и т.п. Все это негативно сказывается на сроке службы процессора. Кроме того, в этом случае автотест не полностью эмулирует действия пользователя, который, как известно, никакие элементы не опрашивает, а тупо залипает в экран, пока страница грузится. Именно эту активность пользователя и эмулирует шаблон проектирования «Сон».
  16. 16. АЛЬТЕРНАТИВЫ • [Решение] Попросить разработчиков встроить механизмы синхронизации загрузки страниц и защиты от так называемого «happy clicking». • [Ответ] Непрофессионально! Вы - автоматизаторы тестирования, а не какие-нибудь там молокососы, бегающие с просьбами к разработчикам. Вы вполне в состоянии справиться с проблемой без постороннего вмешательства.
  17. 17. АЛЬТЕРНАТИВЫ • [Решение] Больше работать, меньше браузать и пить кофе. • [Ответ] Ха. Ха ха. Ха ха ха ха ха.
  18. 18. ТОЛЬКО JAVA? НЕТ! Шаблон «Сон» можно реализовать на любом языке программирования! • C#: System.Threading.Thread.Sleep(5000); • Ruby: sleep 5 • Python: time.sleep(5) • QTP (VBScript): Wait 5
  19. 19. ВОПРОСЫ? =)

×