Upload
borgeir-ingvarsson
View
1.290
Download
0
Embed Size (px)
DESCRIPTION
Citation preview
ШАБЛОНЫ U
I-
АВТОМАТИ
ЗАЦИИ: ПАТТ
ЕРН
«СОН»
АВ
ТО
Р:
CA
PT A
I N C
HA
OS
МОТИВАЦИЯ
• Ваши автотесты постоянно валятся без видимых причин
• Ваше приложение постоянно что-то подгружает втихаря
• Ваше приложение не ожидает, что по нему будут слишком уж быстро кликать
• Ваши автотесты проходят настолько быстро, что вы не успеваете попить кофе и хорошенько побраузать
ПРИМЕНИМОСТЬ
Используйте паттерн «Сон», чтобы:
• Подождать, пока какой-либо элемент появится на странице
• Подождать, пока элемент исчезнет
• Подождать, пока у элемента изменится какой-нибудь атрибут
• Подождать на случай, если элемент может появиться, а может и нет
• Подождать, потому что иначе приложение тупо рухнет
• Просто подождать
СТРУКТУРА
УЧАСТНИКИ
• SleepService – «сервис сна»:
- определяет операцию sleep(), которая позволяет осуществить процедуру ожидания. Альтернативные наименования: pause(), wait() и т.п.
ОТНОШЕНИЯ
SleepService, как правило, не имеет смысла выделять в отдельный класс. Вполне достаточно будет добавить его функциональность в один или несколько из уже существующих утилитных классов (возможно даже, с применением интерфейса или абстрактного класса CanSleep).
Клиенты получают доступ к процедуре сна через вызов метод sleep().
РЕЗУЛЬТАТЫ
• Легко добавить ожидание в любой точке кода
• Любой компонент может при необходимости приостановить свое выполнение
• Вызываемые автотестом методы исполняются обстоятельно и без спешки
• Глядя на исполняющийся тест, можно по крайней мере понимать, что он делает, и при этом успевать заниматься прочими активностями
• Общее время выполнения тестовой сюиты незначительно увеличивается за счет повышения надежности тестов
РЕАЛИЗАЦИЯ
При реализации паттерна «Сон» необходимо рассмотреть следующие вопросы:
• Сон должен блокировать выполнение теста
• Время сна должно быть можно конфигурировать
• Но должно быть можно инициировать сон и просто так, не заморачиваясь на таймаутах
• Процедура сна должна быть масштабируемой
• В случае, если во время сна что-то пошло не так, об этом надо куда-то сообщить
• Но в некоторых случаях можно особо из-за этого не напрягаться
Простейшая реализация:
public static void sleep(long timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Плюсы: просто и элегантно.
Минусы: может засорять лог стектрейсами. Все равно никто не знает, что с ними делать.
ПРИМЕРЫ КОДА
Улучшенная реализация:
public static void sleep(long timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) { }
}
Плюсы: еще проще и элегантнее.
Минусы: отсутствуют.
ПРИМЕРЫ КОДА
ПРИМЕРЫ КОДА
Продвинутая реализация с генерацией исключения:
public static void sleep(long timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage());
}
}
Плюсы: показывает, что вы не какие-нибудь там и умеете генерировать исключения. Обратите внимание, блок throws не требуется, так как это RuntimeException!
Минусы: исключение нужно где-то как-то обработать.
ПРИМЕРЫ КОДА
Продвинутая реализация с логированием предупреждения:
public static void sleep(long timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
LOGGER.warn("sleep() method was interrupted.", e);
}
}
Плюсы: обработка исключения на более высоком уровне больше не требуется!
Минусы: нужно инициализировать логгер. Засоряет лог предупреждениями, которые все равно никто не читает.
ПРИМЕРЫ КОДА
Продвинутая реализация с таймаутом по умолчанию:
private static final long DEFAULT_TIMEOUT = 15000;
public static void sleep() {
sleep(DEFAULT_TIMEOUT);
}
Плюсы: не надо думать о величине таймаута.
Минусы: отсутствуют.
МАСШТАБИРУЕМОСТЬ
Иногда необходимо выполнить ожидание в течение нестандартного отрезка времени. Как же сделать, чтобы процедура сна была масштабируемой?
public void clientMethod() {
…
SleepService.sleep(sleepTime * 8);
…
}
Это решение в лоб, очевидно, не годится, так как неприменимо для случая вызова метода sleep() без параметров. Как же быть?
МАСШТАБИРУЕМОСТЬ
Все очень просто!
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);
…
}
АЛЬТЕРНАТИВЫ
Рассмотрим другие, неправильные, альтернативы решения проблемы:
• [Решение] Реализовать процедуру «поллинга», т.е. опроса элементов в цикле на предмет достижения требуемого условия.
• [Ответ] Но это же неэффективно! Вместо того, чтобы спокойно поспать, автотест должен постоянно обрабатывать какие-то инструкции, делать запросы, анализировать результаты и т.п. Все это негативно сказывается на сроке службы процессора. Кроме того, в этом случае автотест не полностью эмулирует действия пользователя, который, как известно, никакие элементы не опрашивает, а тупо залипает в экран, пока страница грузится. Именно эту активность пользователя и эмулирует шаблон проектирования «Сон».
АЛЬТЕРНАТИВЫ
• [Решение] Попросить разработчиков встроить механизмы синхронизации загрузки страниц и защиты от так называемого «happy clicking».
• [Ответ] Непрофессионально! Вы - автоматизаторы тестирования, а не какие-нибудь там молокососы, бегающие с просьбами к разработчикам. Вы вполне в состоянии справиться с проблемой без постороннего вмешательства.
АЛЬТЕРНАТИВЫ
• [Решение] Больше работать, меньше браузать и пить кофе.
• [Ответ] Ха. Ха ха. Ха ха ха ха ха.
ТОЛЬКО JAVA?
НЕТ!Шаблон «Сон» можно реализовать на любом языке
программирования!
• C#: System.Threading.Thread.Sleep(5000);
• Ruby: sleep 5
• Python: time.sleep(5)
• QTP (VBScript): Wait 5
ВОПРОСЫ?
=)