|
Продолжаем рассмотрение тестирования AJAX приложения с использованием компонентов-"заглушек".
Итак, каких результатов мы добились? Мы знаем, что: - пользовательский интерфейс передает правильные запросы
- пользовательский интерфейс и серверный компонент взаимодействуют правильно
- ожидаемые ошибки корректно обрабатываются пользовательским интерфейсом
Мы не знаем: - отображаются ли данные корректно
- присутствуют ли на странице данные, которые там должны быть
Хотя мы и знаем многое о работе клиента, мы еще не можем утверждать, что он работает корректно. Мы должны протестировать клиент дополнительно – в этом нам помогут автоматизированные тесты интерфейса. Возможные подходы: - добавить в страницы JavaScript управляющий код, который возвращает все элементы страницы (например, с помощью JavaScript Native Interface)
- использовать Selenium, для тестирования интерфейса (поддерживает добавление управляющего кода и использование компонентов-«заглушек»); выполнить проверки:
- существования элементов
- активности кнопок
- добавления полос прокрутки при необходимости
Остальную работу за нас сделает модуль GwtTestcase. Из проблем, которые часто возникают при тестировании с помощью Selenium, хочется отметить чрезмерное использование XPath для обращения к элементам страниц. Вследствие этого, изменения в объектной модели документа (DOM) приводят к поломке тестов. Один из способов обойти эту проблему – использовать JavaScript-хуки: они добавляются только в случае, если приложение запущено со специальным флагом «тестируется», и позволяют обращаться к необходимым элементам напрямую. Использование JavaScript-хуков предоставляет возможность более быстрого нахождения проблем в тестах и устранения их без изменения соответствующих тестов: маленький и быстрый JsUnit-тест определит, работает ли конкретный хук, и, если нет, его исправление требует одной строчки кода.
Чего мы достигли теперь? Мы знаем, что: - пользовательский интерфейс передает правильные запросы
- пользовательский интерфейс и серверный компонент взаимодействуют правильно
- ожидаемые ошибки корректно обрабатываются пользовательским интерфейсом
- элементы отображаются корректно
- объектная модель документа правильна
Мы не знаем: - работают ли другие компоненты (не являющиеся частью пользовательского интерфейса) корректно
Проверка функциональности серверного компонента (StoreService) Методам, входящим в StoreService, необходимо полное юнит-тестирование. Для выполнения юнит-тестов нам понадобится модуль-«заглушка» backend-компонента, MockOfficeAdministration, который пригодится нам в дальнейшем. Наша главная цель на этом этапе – проверить, что: - каждый метод интерфейса StoreService работает корректно, даже в случае ошибок в передаче данных между ним и backend-компонентом
- каждый метод возвращает ожидаемые результаты
Используя модуль-«заглушку» MockOfficeAdministration, мы можем не беспокоиться о подготовке данных, и внедрение ошибок не составит проблем. Кроме тестирования базовой функциональности, например: - все ли ожидаемые данные получены
- не получены ли какие-либо лишние данные
- корректно ли обрабатывается ситуация, когда никаких данных не найдено
… мы также можем проверить обработку: - некорректных данных
- данных избыточного размера
- пустых данных
- обработки исключений
- превышения времени ожидания отклика
- проблем одновременного доступа
Замена настоящего backend-компонента на компонент-«заглушку» не должна представлять проблем, поскольку использование механизма RPC уже вынудило нас определить интерфейсы для сервера; все, что осталось сделать – определить интерфейс-«заглушку» и использовать его вместо «настоящего». Возможно, вы предпочтете запустить интерфейс-«заглушку» на той же рабочей станции, на которой вы выполняете тесты – для ускорения выполнения тестов. Примеры тестовых сценариев: - получить список офисов, когда backend-“заглушка»:
- возвращает пустой список
- возвращает список из 100 офисов, один в неправильном формате
- возвращает список из 100 офисов, NULL вместо одного из них
- …
- генерирует исключение
- не возвращает ничего до превышения времени ожидания отклика
- получить список ресурсов для выбранного офиса, когда backend-“заглушка» возвращает:
- получить список ресурсов для выбранного офиса, когда backend-“заглушка» блокирует обращение и:
- генерирует еще одно обращение к тому же ресурсу в то же время
- …
Теперь мы знаем, что: - пользовательский интерфейс работает корректно в изоляции от других компонентов
- серверный компонент StoreService корректно обращается к backend-компоненту
- серверный компонент StoreService корректно обрабатывает ошибки
- немного о работе приложения при одновременном обращении
Мы не знаем: - действительно ли backend-компонент ожидает запросы, передаваемые серверным компонентом
Нетрудно видеть, что мы можем проверить аналогично OfficeAdministration (backend-компонент) с использованием “заглушки» MockBigTable. После этого, мы будем знать, что: - backend-компонент корректно читает данные из базы данных
- бизнес-логика корректно обрабатывается backend-компонентом
- backend-компонент корректно обрабатывает ошибки
- backend-компонент корректно обрабатывает недостающие данные
Мы не знаем: - используется ли backend-компонент корректно, т.е. в соответствии со спецификацией
Проверка взаимодействия backend-компонента и серверного компонента Теперь проверим, как OfficeAdministration (backend-компонент) и StoreService (серверный компонент) взаимодействуют друг с другом. Это обязательная задача, и не такая уж сложная – следующие замечания помогут сделать эти тесты быстрыми и легкими: - легкость тестирования (через Java API)
- легкость понимания
- в идеале, наличие всей бизнес-логики
- доступность на ранних этапах разработки
- быстрое выполнение (особенно с использованием модуля-«заглушки» для базы данных)
- не требует значительных объемов поддержки (благодаря стабильности интерфейсов)
- потенциально является подмножеством тестовых сценариев для серверного компонента в отдельности
Наши результаты по окончании этого этапа – мы знаем, что: - пользовательский интерфейс работает корректно в изоляции от других компонентов
- OfficeAdministration (backend-компонент) и StoreService (серверный компонент) корректно взаимодействуют друг с другом
Мы пока не знаем: - доходят ли результаты их взаимодействия до пользователя
Последний, но не наименее важный, этап – системный тест Наконец, соберем все компоненты вместе и проведем «большой» системный тест. В нашем случае, стандартным сценарием будет: - ввод «хороших» значений для тестирования в базу данных:
- 5 офисов с 5 ресурсами в каждом, в количестве 5 штук каждый
- использование Selenium (и JavaScript-хуков) для:
- взаимодействия с навигационной панелью
- снятия/добавления пометки для офиса
- добавления ресурсов
- …
Мы знаем теперь, что все компоненты в совокупности позволяют выполнение одного типичного пользовательского сценария. Аналогичные тесты должны быть выполнены для каждого действия, доступного в пользовательском интерфейсе. Наибольшим преимуществом является то, что теперь нам надо проверять только взаимодействие между компонентами – граничные значения, ошибки сети и т.д. проверять не надо, мы это уже сделали. Заключение Для успеха нашего подхода необходимо: - понимание системы
- понимание используемой платформы
- понимание того, что и где может работать неправильно
- создание тестов, начиная с первых этапов разработки
- инвестиции в инфраструктуру для тестирования (модули-«заглушки» и т.п.)
Результатом станет: - увеличение скорости выполнения тестов
- уменьшение затрат на поддержку тестов по причине:
- разделенного авторства
- раннего выполнения => ранних обнаружений ошибок => ранних исправлений
- уменьшение времени получения результатов тестирования
- упрощение отладки и поиска дефектов благодаря меньшему числу ошибочных отказов
(по материалам Google Testing Blog) |