Тестируй веб-сайты вместе с Badboy. Часть 1

Разработка программного обеспечения — не самая простая наука. И уж тем более она не сводится к знанию языков программирования и разных библиотечек с готовыми наработками. Если создавать что-то не "для себя" или "на потеху", а заниматься разработкой ПО профессионально, зарабатывать деньги, то необходимо качественно пройтись по всем шагам жизненного цикла ПО: от планирования до сопровождения.

Сегодня рассказ будет посвящен такому этапу, как тестирование. Тестирование — один из важнейших шагов в процессе разработки. Возможен вариант, когда после создания ПО, но до передачи заказчику выполняется тестирование качества, поиск ошибок. Возможен и другой стиль тестирования, когда оно идет одновременно с разработкой ПО. В этом случае затраты времени больше, чем в первом варианте, но и качество продукта будет выше. Условно тесты делятся "по шагам" и "по способам". Шаги — это юнит-тестирование (оно же модульное тестирование), интеграционное тестирование, системное тестирование. В первом случае тестированию подвергаются наименьшие части приложения: обычно это отдельный класс и его методы. В случаях, если класс нуждается для обеспечения своей работы в еще одном классе, а тот класс — в третьем и т.д., то для лучшего контроля нужно отделить тестируемые классы друг от друга, заменить их с помощью "заглушек", "имитаций". Например, если мы тестируем код класса, принимающего имя и пароль, а затем проверяющего его по базе данных (а это уже второй класс), то можно заменить класс, работающий с реальными данными, "имитацией", которая не обращается к базе данных за сведениями, а хранит эти данные внутри самого класса. Т.е. предполагается, что имитация должна быть достаточно проста, чтобы не содержать ошибок — в противном случае говорить о модульном тестировании нельзя. После модульного тестирования мы начинаем говорить, что тесты следует выполнить для всего приложения в сборе — этим занимается интеграционное тестирование. Этот вариант является достаточно трудоемким: выполнять "сборку" приложения в единое целое из множества разрозненных модулей требует много времени, и это нельзя делать каждые 10 минут или после внесения правок в один из методов. Здесь имеет смысл использовать системы автоматического тестирования, которые срабатывают по некоторому закону (например, в конце рабочего дня или как только изменения были помещены в общий репозиторий). Тогда скрипт тестирования вытягивает из репозитория SVN файлы и нужные для работы библиотеки, затем выполняет тесты. Отчеты же о найденных ошибках публикуются и доступны для пришедших с утречка программистов. Третий вид тестирования — системное — делится на альфа-тестирование и бета- тестирование. В первом случае мы набираем небольшую команду тестеров (работающих в нашей организации), которые пытаются использовать программу, ищут в ней ошибки. Бета-тестирование похоже на альфа-тестирование, но отличается кругом привлеченных лиц: их больше, и это посторонние (не наши сотрудники и работающие не за зарплату) люди. Бета-тестирование — это еще и инструмент продвижения программы на рынок: мы можем представить бета- тестерам бесплатную версию ПО, даем скидки на последующую покупку, надеемся на то, что тестеры расскажут о "классной" программе своим друзьям. Очевидно, что (а кое-кому — совсем не очевидно), что выпускать на публичный тест недоделанную и "глючную" программу — не самый умный поступок. Сегодняшний рассказ будет посвящен специальному инструменту для автоматизации системного и интеграционного тестирования при разработке именно веб-приложений — bayboy.

Badboy похож на магнитофон: вы открываете страницу сайта, жмете на кнопку "начать запись" и затем работаете с сайтом (ходите по ссылкам, отправляете формы) — все эти действия badboy записывает в виде сценария действий. Завершив запись, вы можете проиграть ее в любой момент и оценить результат выполнения каждого шага (ага, после отправки формы авторизации на экране должна была появиться надпись "Привет, Вася", а ее нет — значит, тест провален). Badboy — не единственный продукт такого класса, и наверняка не самый лучший (тут я надеюсь на то, что те, кто профессионально занимается QA, выскажутся и поделятся своим опытом). С badboy я познакомился несколько месяцев назад, когда передо мной поставили задачу научить человека писать сценарии тестирования веб-приложений. Самым известным среди подобных инструментов для тестирования является Jmeter ( сайт ). К сожалению, он не прост и совсем не похож на большой магнитофон с парой кнопок "запись-воспроизведение", поэтому я провел небольшой поиск в internet и нашел badboy. Оказалось, что badboy (такой простой и понятный) не только записывает сценарий, но и умеет экспортировать сценарии в jemeter (а там мы можем скрипт "обработать напильником" до нужной кондиции). Такая связка показалась мне наилучшим способом для быстрого старта всем, кто хочет заняться веб-тестированием.

Предположим, вы загрузили и установили Badboy (домашний сайт проекта: сайт ). Собственно говоря, Badboy не бесплатный (в отличие от Jmeter), но никаких проблем в использовании пробной версии вместо платной полной я не встретил. Очень приятно, что помимо неплохой документации в составе badboy есть почти интерактивный учебник, показывающий по шагам основные приемы работы (меню Help -> Tutorial). Теперь разберемся с терминологией: основные понятия — это Suites, Tests, Steps. В общем случае тестируемое приложение нетривиально: оно состоит из набора страниц, которые можно использовать по-разному (например, веб-интерфейс для почтовой системы содержит пусть и не очень много страничек, но большое количество различных действий). Очевидно, что глупо создать суперогромный скрипт, тестирующий абсолютно все. Поэтому мы представляем тесты как логически упорядоченное дерево. Верхний уровень теста — например, тестирование открытой части сайта и закрытой. Затем тест открытой части состоит из теста новостей, теста формы регистрации и т.д. Количество таких вложенных уровней не ограничивается. Suite — это набор тестов, а каждый тест (Test) состоит из шагов (Steps). Step — это элементарная единица работы (имитировать нажатие на кнопку, отправить форму и т.д.). На рис. 1 окно с деревом suite -> test -> step имеет пометку "1". Что и как записывает badboy? Когда вы нажали на ссылку или кнопку, то badboy выжидает 500 миллисекунд, и, если в течение этого времени браузер начал загрузку новой страницы, относит ваше действие к разряду активных, если действия нет — к разряду пассивных событий. Все активные действия записываются в сценарий (и это без вариантов, хотя впоследствии вы можете подправить сценарий вручную), будут ли записаны пассивные действия, определяется в меню Preferences на закладке recording. Там же можно настроить, будут ли записываться запросы браузера к странице, если они были инициированы с помощью javascript. Далее: есть два режима записи: Request Mode и Navigation Mode. В первом случае badboy помещает в сценарий запросы, посылаемые браузером, во втором случае имитирует действия человека (те же нажатия на кнопки). Эти режимы следует четко отделять друг от друга и понимать, когда какой из них использовать. Например, если вы тестируете форму с кнопкой и использовали первый режим (Request Mode), то Badboy записал, какие данные отправляются серверу при активации кнопки. Теперь предположим, что кнопка куда-то пропала — очевидно, что тест должен быть провален. Ничуть: первый режим отправляет веб-запрос, а не пытается "нажать" на кнопку, чтобы запрос был отправлен браузером. Или еще пример: по нажатию на кнопку отправляется форма, часть полей которой является вычисляемой браузером (например, текущее время). Очевидно, что в режиме Request Mode данные будут отравляться одни и те же. С другой стороны, при тестировании производительности сервера, когда веб-приложению посылается одновременно несколько сотен запросов, режим Navigation Mode неприемлем: просто физически невозможно открыть эту сотню браузеров, имитировать клик по кнопке, чтобы выдержать темп тестирования. Отсюда вывод: для тестирования корректности интерфейса используем режим Navigation Mode, для теста функциональности сайта и его производительности — режим Request Mode (для переключения в ходе записи сценария между этими двумя режимами просто зажмите пару клавиш Ctrl+Alt).

Попробуем записать небольшой сценарий. Для этого включаем режим записи (клавиша F2). Затем в адресной строке вводим адрес сайта и видим, как в дереве Suite -> Test -> Step появляется новый узел (пока идет выполнение запроса, цвет элемента красный). После завершения загрузки попробуйте раскрыть только что добавленный узел — там вы увидите время, которое было затрачено на загрузку страницы, ее размер. Все выполняемые вами действия будут записаны — попробуйте открыть всплывающее окно и тут же его закрыть (при этом в дерево шагов будет добавлено действие Close Active Browser). Для качественного теста нам потребуется не просто набор страниц, но сайт, где можно отправить форму (например, регистрация на почтовом сайте). Посмотрите на рис. 2 — там я показал, как будет выглядеть запрос, выполненный из формы: если раскрыть узел с названием запрошенной страницы, то мы увидим перечисление всех полей, которые были посланы на сервер. На этом описание методики записи теста будем считать завершенным — не забывайте только разбивать тест на части (на панели инструментов рядом с кнопками, запускающими и останавливающими запись, есть кнопки Create New Suite и Create New Test). Далее: мало записать последовательность действий — нужно добавить условия, проверяемые после каждого шага. Если мы так не сделаем, то невозможно будет определить, правильно ли работает сайт, разве что сидеть перед экраном и на глазок оценивать, те ли страницы загружаются badboy'ем. Для этого остановим запись и перейдем к первому шагу в сценарии (если вызвать контекстное меню для произвольного Step'а, затем выбрать пункт Play, то этот шаг будет проигран, и в основной области экрана badboy будет загружена соответствующая страница). Там же, в контекстном меню, есть функции для удаления Step'ов из сценария или их временного отключения (Disable). Итак: есть два способа добавить условие, проверяемое после выполнения Step'а: во-первых, на панели кнопок есть функция Create Easy Assertion: ее назначение — добавить в сценарий Assertion (утверждение), состоящее из одного Check'а (условия). Assertion в общем случае состоит из нескольких check'ов, а check — это то, что должно быть проверено на странице. И если check не выполняется, то не выполняется и родительский для него Assertion. Самым простым видом check'ов является проверка того, что на странице присутствует какой-то кусочек текста (например, после отправки формы авторизации, если на странице не найдется фраза "Здравствуй, Петя", то мы уже знаем, что процедура входа не была выполнена, и тест считается проваленным). Именно такой check создается при нажатии Create Easy Assertion. Можно создавать Assertion и через контекстное меню: здесь надо выбрать пункт Insert -> Assertion — так мы добавим после Step'а условие. Вот только Assertion будет пуст (без вложенного check'а), но мы это легко поправим. Для этого на панели инструментов (на рис. 1 она помечена цифрой "2") перейдите на закладку checks и перетащите внутрь Assertion'а один из доступных check'ов (для каждого из них с помощью контекстного меню и пункта Properties можно изменить условия проверки):

1. Content Check — проверка наличия в тексте страницы (в любом ее месте) некоторой фразы. В качестве параметров настройки check'а задается собственно текст, который нужно найти на странице. Также можно изменить условие на противоположное: check будет пройден, если только эта фраза не будет найдена. Самое приятное в том, что можно искать не просто кусочек текста, но и регулярное выражение. Да, еще: если ваш сайт использует фреймы, то badboy умеет искать текст и внутри них.
2. Color Check служит для проверки того, что в некоторых координатах страницы (можно их указать с некоторой дельтой погрешности) должен находиться пиксель заданного цвета. Проще всего после добавления check'а в окне его настроек нажать кнопку Capture, затем выполнить клик по нужному месту веб-страницы, открытой в badboy (координаты клика и цвет пикселя в этом месте будут автоматически назначены как условие check'а).
3. Response Check — его назначение — оценить время загрузки страницы или ее размер.
4. Jscript Check представляет самую гибкую функцию оценки — вы можете в окне свойств check'а в специальное текстовое поле ввести фрагмент кода на javascript (результат работы должен быть логической величиной и будет значением check'а).
5. Summary Check дает возможность оценить итоговые результаты работы того Step'а, в который вложен данный check. Например, мы говорим, что операция загрузки страницы должна быть выполнена 100 раз, и, если из них более 5 операций завершились timeout'ом, то тест провален.
6. Variable Check служит для проверки того, что некоторая переменная (что такое переменные, и как их использовать, я расскажу чуть позже) равна или не равна некоторой величине.

Наполнив Assertion условиями (check), вызовем контекстное меню и рассмотрим, какими параметрами Assertion'а можно управлять. Прежде всего, настроим поведение теста в случае, если произошел сбой, т.е. какой-либо из check'ов был провален (падающий список для пункта When violated -> Action). Можно потребовать вывести окно сообщения о возникшей ошибке (см. рис. 3), в падающем списке When Violated -> Action выберите пункт Alert me. Можно потребовать сделать скриншот экрана браузера с ошибкой. Где можно увидеть этот скриншот? Картинки не складываются в какую-то папку (это было бы неудобно для последующего поиска). Вместо этого после выполнения теста к узлу дерева Assetion будут добавлены еще вложенные узлы, содержащие статус выполнения check'а (только если check был провален), и, если выполнить двойной клик по этому узлу, то откроется картинка скриншота. Assertion применяется к step'у, после которого он размещен в дереве проекта, однако бывает ситуация, когда некоторое условие должно проверяться постоянно (для каждого из step'ов в тесте). Например, после процедуры авторизации на всех страницах в углу должна быть надпись "Пользователь: Вася". За настройку подобной "глобальности" (все Step'ы в рамках текущего Test'а) отметьте в свойствах Assertion галочку Cascade To Following Items. Помните только, что Assertion не будет применяться к шагам, расположенным в том же Step'е, но раньше, чем сам Assertion, а если расположить такой "глобальный" Assertion внутри не Test'а, а целой Suite, то условие будет проверяться для всех Test'ов и вложенных в них Step'ов. Если мы проверили check, и он был провален, то не всегда имеет смысл продолжать дальнейшее выполнение теста (если операция авторизации на почтовом сайте была неуспешна, то какой смысл выполнять остальные тесты?). Обратите внимание на падающий список с вариантами When Violated -> Continuation. Именно здесь вы можете указать, что хотите либо Continue from same position (тест будет продолжаться дальше), Abort* (несколько вариантов команд, начинающихся со слова "Abort", позволяют прервать выполнение текущего теста или всего набора тестов). С вариантом Repeat The Containing step нужно быть острожным, т.к. он приводит к повторному выполнению того теста, в который вложен данный Assertion, и, если условие никогда не выполнится, то вы попадаете в настоящий бесконечный цикл. Теперь, создав заготовку теста, мы можем его "проиграть" — для этого используйте снова контекстное меню на любом из пунктов дерева (на Suite, Test или отдельном Step'е) и выберите пункт Play. Вы можете наблюдать за работой badboy не только на основном экране, также узлы дерева проекта по очереди меняют свой цвет на зеленый (признак того, что этот шаг сейчас выполняется). После завершения теста удобно окинуть взглядом выполненные шаги и статусы их завершения (меню View -> Report). По умолчанию badboy при очередном запуске теста не очищает добавленные на дерево проекта фиктивные узлы (результаты проверок check'ов, время выполнения запросов) — для этого используйте меню Tools -> Clear Responses.

В следующий раз я продолжу рассказ об badboy. Необходимо показать, как можно не просто "проигрывать" один и тот же набор шагов, но и менять их, работать с переменными, как выполнять тестирование под нагрузкой.

black-zorro@tut.by, black-zorro.com


Компьютерная газета. Статья была опубликована в номере 15 за 2008 год в рубрике soft

©1997-2022 Компьютерная газета