Разделы портала

Онлайн-тренинги

.
Как внедрить тестирование пользовательского интерфейса без головной боли
25.05.2010 09:32

Автор: Gojko Adzic
Перевод:
Дмитрий Дудников по заказу Software-Testing.RU
Оригинальная публикация

Я сейчас пишу новую книгу и в связи с этим опрашиваю множество команд, внедривших приемочное тестирование. Большинство из уже опрошенных не в одном, так в другом месте наступали на грабли при автоматизации тестирования пользовательского интерфейса (UI). Пообщавшись несколько недель назад на Agile Acceptance Testing Days в Бельгии с некоторыми участниками, которые как раз опасно приблизились к тому месту, где спрятаны грабли, я хочу представить вашему вниманию хорошие, на мой взгляд, подходы к автоматизации UI-тестирования.

Некоторое время назад я уже высказывался против автоматизации тестирования пользовательского интерфейса, поэтому не буду повторяться. Однако многие из команд, с которыми я общался, судя по всему, предпочитают автоматизацию именно на этом уровне, или думают, что для подтверждения требуемой бизнес-функциональности необходимо тестирование на этом уровне. Почти все эти команды через 6-9 месяцев после первых попыток автоматизации обнаруживали, что цена поддержки UI-тестов больше, чем получаемая от них выгода. Многие в этот момент забрасывали свои тесты и благополучно теряли вложенные в них усилия. Если вам все-таки необходимо выполнить автоматизацию UI-тестов (в чем я сильно сомневаюсь), то ниже вы найдете рекомендации, как сделать так, чтобы в дальнейшем цена их поддержки не оказалась слишком высокой.

Три уровня автоматизации UI-тестирования

При проектировании функциональных тестов для пользовательского интерфейса полезно представлять автоматизацию распределенной по трем уровням:

  • Уровень бизнес-правил/функциональных возможностей: что этот тест показывает или проверяет? Например, покупателям, заказавшим две и более книги, предлагается бесплатная доставка.
  • Уровень последовательности действий (workflow) в пользовательском интерфейсе: описание на высоком уровне того, что должен проделать пользователь, чтобы воспользоваться функциональной возможностью. Например, положить две книги в корзину, ввести адрес и убедиться, что доставка бесплатна.
  • Уровень технических деталей: какие технические шаги необходимо сделать, чтобы воспользоваться функциональной возможностью? Например, открыть страницу магазина, авторизоваться как “testuser” с паролем “testpassword”, перейти на страницу “/book”, щелкнуть на первом изображении с CSS-классом “book”, дождаться загрузки страницы, щелкнуть ссылку “Купить сейчас” … и так далее.

К тому моменту, когда проинтервьюированные мной команды обнаруживали, что UI-тесты не окупаются, они описывали их только на техническом уровне (крайний случай – это записанные «рекордером» тестовые скрипты, где нет никакого разделения на уровни вообще и человеку это прочитать совершенно невозможно).

Такие тесты очень чувствительны к изменениям в пользовательском интерфейсе, и многие из них могут перестать работать даже при незначительных изменениях. Кроме того, технический уровень перегружен текстом, поэтому очень трудно понять, что сломалось, когда тест не проходит.

Некоторые команды описывают тесты на уровне workflow, который немного более стабилен. Такие тесты не привязаны к верстке (layout), однако, они привязаны к реализации пользовательского интерфейса – когда изменяется последовательность действий на странице или лежащая в основе технология, эти тесты перестают работать.

Прежде чем вы решите писать сердитые комментарии о том, что технический уровень – это единственное, что реально работает с тестируемым приложением, я хочу сказать: да, нам нужен технический уровень. Однако есть серьезные аргументы за то, чтобы не оставаться только на техническом уровне.

Стабильность тестов высокого уровня проистекает из того, что бизнес-правила не меняются так быстро, как их техническая реализация. Технологии меняются быстрее, чем бизнес. Чем ближе ваши тесты к бизнес-правилам, тем они стабильнее. Заметьте, это совсем не означает, что тесты не будут выполняться через пользовательский интерфейс. Это означает, что они определяются способом, не привязанным к конкретному пользовательскому интерфейсу.

Использование трех разных уровней хорошо потому, что это позволяет нам писать UI-тесты, которые легко понимать, удобно разрабатывать и относительно недорого поддерживать. Все это – следствие трехуровневой иерархии концепций. Проверка того, что доставка доступна для двух книг (бизнес-правило), включает в себя отправку книги в корзину (последовательность действий), а отправка в корзину включает в себя последовательность технических шагов. То же самое и для ввода адреса. Такая иерархическая декомпозиция и группировка нескольких понятий более низкого уровня в одно понятие более высокого уровня снижает смысловую нагрузку и способствует повторному использованию.

Легко понимать

Снизу вверх понятность тестов возрастает. На техническом уровне тесты перегружены техническими деталями – за деревьями не видно леса. На уровне последовательности действий (workflow) тесты описывают, какие действия надо сделать, чтобы достичь определенного результата. Эти описания легче понять, но в них по-прежнему слишком много деталей, чтобы эффективно описывать различные варианты поведения. На уровне бизнес-правил суть теста может быть изложена в относительно краткой форме. Мы можем использовать этот уровень, чтобы легко описать все варианты. Гораздо проще описать альтернативную ситуацию в виде: «бесплатная доставка не предоставляется покупателям, заказавшим одну книгу», чем рассказывать об авторизации, помещении только одной книги в корзину, проверке и т.д. Я даже не говорю о том, какая смысловая перегрузка получилась бы, если бы мы попытались изложить это в виде кликов по ссылкам и checkbox’ам.

Удобно разрабатывать

Снизу вверх уровень технических подробностей в тестах уменьшается. На нижнем уровне (уровне технических действий) для написания теста вам необходимы люди, понимающие дизайн системы, протокол HTTP, интерфейс DOM и тому подобное. Чтобы написать тест на уровне последовательности действий (workflow) вам достаточно понимать, какие действия пользователь может совершить, находясь на той или иной странице сайта. На уровне бизнес-правил вам достаточно понимать только сами бизнес-правила. Имея набор компонентов верхнего уровня (например, «авторизоваться», «добавить книгу») тестировщики, не являющиеся ни специалистами по автоматизации, ни бизнес-пользователями, могут прекрасно описывать шаги второго уровня. Это позволяет им эффективнее участвовать в процессе разработки тестов и снижает нагрузку на разработчиков.

Еще более важно то, что тесты на уровнях бизнес-правил и workflow могут быть написаны ещё до того, как пользовательский интерфейс будет готов, а иногда даже раньше, чем начнется разработка. При этом тесты могут использоваться как руководство для разработки и как критерий приемки.

Относительно недорого поддерживать

Уровень бизнес-правил не привязан к дизайну или workflow конкретного веб-сайта, поэтому он остается стабильным и неизменным в ходе большинства изменений пользовательского интерфейса, будь то изменения верстки или улучшения workflow.

Уровень workflow пользовательского интерфейса завязан на последовательность действий, поэтому когда меняется набор действий, необходимых для достижения некоторого результата, необходимо переписать только этот отдельный workflow. Технический уровень привязан к верстке страниц, поэтому когда верстка меняется, приходится переписывать или перезаписывать только реализацию отдельных шагов второго уровня, на которые она влияет (не изменяя описания теста на бизнес-уровне или на уровне workflow).

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

Практическое применение

Существует много способов реализовать эту идею на практике. Большинство инструментов автоматизации тестирования предоставляют возможность выделения одного или двух уровней. Лично я считаю, что Cucumber нашел золотую середину в тестировании пользовательских интерфейсов, основанных на браузерах. В Cucumber описания шагов, реализованные на языке программирования, естественным образом соответствуют уровню технических действий. Эти описания шагов затем могут быть использованы для создания сценариев (уровень workflow пользовательского интерфейса), а описания сценариев могут быть эффективно использованы для описания тестов на уровне бизнес-правил.

Новый механизм запуска тестов SLIM для FitNesse предоставляет аналогичные уровни. Нижний, технический, уровень (fixture) естественным образом соответствует нашему уровню технических действий. «Сценарии» (scenario definitions) могут быть использованы для описания на уровне последовательности действий. И наконец «таблицы сценариев» (scenario tables) вполне подходят для краткого представления уровня бизнес-правил.

Robot Framework использует для описания тестов «ключевые слова» (“keywords”), и позволяет определять их либо напрямую в коде (который таким образом превращается в технический уровень), либо сочетанием существующих ключевых слов (давая таким образом уровень workflow и уровень бизнес-правил).

Шаблон проектирования Page Object, рекомендуемый для использования с инструментами Selenium и WebDriver, безусловно хорош, но несколько недоработан. Он требует инкапсуляции уровня технических действий в более высокий уровень функциональности «страниц», которые затем используются для описания workflow. Этой идее недостает консолидации workflow в более высокий уровень бизнес-правил, поэтому вам придется создавать этот уровень самим в коде. Энтони Маркано (Antony Marcano) также обратил внимание на CITCON Europe-2009 на тот факт, что пользователи думают о бизнес-действиях, а не о функциональности страниц, поэтому использование объектов-«страниц» может быть не самым лучшим подходом.

TextTest работает с xUseCase recorders, это интересный трюк, позволяющий записывать определения шагов на техническом уровне без программирования их вручную. Это может быть полезно для тестирования интерфейсов толстых клиентских приложений, для которых средства автоматизации не так развиты, как веб-приложений.

С помощью Twist вы можете записать технический уровень, и он сам создаст для вас определения fixture. Вместо использования их в тесте напрямую вы можете использовать «абстрактные концепции» (“abstract concepts”) для объединения шагов в workflow, а затем использовать их для тестирования бизнес-уровня. Либо вы можете сложить вместе методы fixture, чтобы получить действия workflow в виде кода.

Будьте осторожны с текстовой автоматизацией

Декомпозиция UI-тестов на три уровня представляется мне хорошей практикой в целом. Однако автоматизировать или нет тестирование пользовательского интерфейса – каждая команда должна решать в зависимости от своих обстоятельств.

Реализация уровня workflow в виде обычного текста, а не программного кода («ключевые слова» верхнего уровня в Robot Framework, «абстрактные концепции» Twist, «таблицы сценариев» SLIM), позволяет пользователям и тестировщикам, не являющимся специалистами по автоматизации, разрабатывать и поддерживать тесты. Для некоторых команд это является важным преимуществом, поскольку разработчики в этом случае могут сосредоточиться на других вещах, а тестировщики смогут подключиться на более ранней стадии. Однако это означает, что для таких тестов не будут доступны возможности автоматизированного рефакторинга, проверки синтаксиса и тому подобное.

Реализация уровня workflow в виде программного кода обеспечивает большую степень интеграции и повторного использования, а в некоторых случаях можно использовать части реализации, находящиеся под пользовательским интерфейсом, без разрушения описаний более высокого уровня. Однако автоматизация такого уровня требует привлечения сотрудников с навыками программирования.

Интересный подход я встретил у одной из проинтервьюированных мной команд. Он заключается в обучении тестировщиков навыкам программирования в степени, достаточной для реализации уровня пользовательских действий. Это не требует продвинутых знаний в программировании, а на случай затруднений рядом всегда есть готовые помочь разработчики.

Что необходимо запомнить

Чтобы не наступать на грабли при тестировании пользовательских интерфейсов запомните следущее:

  • Помните о трех уровнях автоматизации UI-тестирования: бизнес-правила, последовательность действий (workflow) и технический уровень.
  • В случае, если автоматизация UI-тестирования на уровне workflow реализуется в виде обычного текста, убедитесь, что вы расположили над ним дополнительный уровень абстракции и явным образом описали бизнес-правила. Не описывайте правила как последовательности действий (только если они действительно не сформулированы так в требованиях – и даже в этом случае чаще всего полезно описывать правила как конечные автоматы).
  • В случае, если автоматизация UI-тестирования на уровне workflow реализуется в виде программного кода, выделяйте технические действия, необходимые для выполнения шагов, в отдельный слой. Используйте повторно определения шагов, чтобы в дальнейшем получить большую стабильность и облегчить поддержку.
  • Будьте осторожны при использовании для автоматизации UI-тестов обычного текста.