Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Конференция «Технологии управления данными 2018»
СУБД, платформы, инструменты, реальные проекты.
29 ноября 2018 г.
2008 г.

Автоматизация тестирования web-приложений, основанных на скриптовых языках

Д. В. Силаков

Назад Содержание

5. Тестирование LSB Навигатора

В рамках совместного проекта ИСП РАН и Linux Foundation по развитию инфраструктуры стандарта LSB в ИСП РАН разрабатывается LSB Навигатор (LSB Navigator) [14] — Web-приложение, позволяющее пользователям в удобной и доступной форме получать и анализировать данные, находящиеся в спецификационной базе данных LSB [15]. LSB Навигатор полностью написан на PHP и в настоящее время представляет собой 120 скриптов, содержащих около 17000 строк кода. В процессе работы может создаваться порядка 250 различных типов страниц. Количество используемых параметров запроса варьируется от 5 до 50 для разных скриптов. База данных LSB содержит 62 таблицы, а также 167 так называемых кэш-таблиц, создаваемых автоматически и используемых для ускорения работы Навигатора. По состоянию на декабрь 2007 года (дата выхода LSB 3.2), обычные таблицы содержат около 18 миллионов записей, кэш-таблицы — около 6 миллионов. Общее количество различных страниц, которые можно получить при работе с приложением, составляет около ста миллионов.

LSB Навигатор активно развивается, и ввиду достаточно сложной внутренней структуры программы актуальной является проблема регрессионного тестирования — изменения в некоторых участках кода могут повлиять на десятки страниц, и определение и проверка таких страниц вручную — трудоемкий процесс. Кроме того, для постоянно появляющихся новых возможностей необходимы новые тесты. Применяемый подход позволил за короткое время получить достаточно качественный набор регрессионных тестов. Более того, тесты для новых возможностей генерируются без участия человека; таким образом, регрессионный набор автоматически поддерживается в актуальном состоянии.

5.1. Анализ кода

Код LSB Навигатора имеет ряд особенностей, благодаря которым для анализа скриптов в целях генерации тестов не требуется полноценного парсера PHP. Так, каждый скрипт, к которому можно обратиться из адресной строки браузера, имеет следующую структуру:

<инициализационная часть; возможно, некоторые проверки параметров запроса>
switch( $_REQUEST['cmd'] ) {
	case "cmd1":
		function1( $_REQUEST["param1"], $_REQUEST["param2"], ... );
		break;
	case "cmd2":
		function2( ... );
		break;
	...
	case "":
	default:
		default_function( ... );
}

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

Помимо массива $_REQUEST, используются также обращения к массивам $_GET и $_POST. Инициализационная часть также может содержать обращения к этим массивам, однако она, как правило, не содержит ветвлений и проста для анализа.

Основная же функциональность скрипта заключается в проверке значения параметра 'cmd' и вызова соответствующих функций в зависимости от этого значения. Аргументы для функций формируются из других параметров запроса, причем для различных значений 'cmd' (т.е. для разных функций) могут использоваться различные параметры.

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

  • определение параметров запроса, используемых в инициализационной части;

  • определение списка значений параметра 'cmd', встречающихся в инструкциях 'case';

  • определение имен и возможных значений параметров запроса, используемых в исходном коде внутри каждого блока 'case'; при этом производится рекурсивный анализ вложенных конструкции 'if' и 'switch' внутри каждой ветви.

Заметим, что анализ вложенных конструкций 'switch' может быть применен ко всему скрипту целиком, начиная с предложения 'switch( $_REQUEST['cmd'] )', и явного выделения такого предложения не требуется. Однако в тестах для LSB Навигатора использование $_REQUEST['cmd'] рассматривается отдельно — в данном случае стоит цель проверить реакцию приложения на все возможные значения параметра 'cmd', в то время как для остальных параметров часть значений может быть либо опущена, либо использована только с определенными значениями других параметров.

Вызываемые функции function1, function2, ..., default_function определены в отдельных файлах, к которым нельзя получить доступ через Web-браузер, и которые не содержат обращений непосредственно к массивам $_REQUEST, $_POST или $_GET. В настоящее время тела вызываемых функций не анализируются, хотя потенциально функции могу вести себя по-разному в зависимости от значений своих аргументов, и такой анализ мог бы способствовать повышению качества тестов.

5.2. Генерация тестов

На основе сведений, собранных в процессе анализа скрипта, производится генерация тестов для этого скрипта. Тест представляет собой ссылку вида

http://test.host.name/script_name?param1=value1¶m2=value2...

В настоящее время получение страниц, соответствующих сгенерированным ссылкам, возлагается на внешнюю программу (утилиту wget). При этом все параметры помещаются непосредственно в ссылку, т.е. фактически являются параметрами типа GET. Поскольку реально приложение может ожидать получения некоторых параметров только методом POST, то на время тестирования версии приложения обращения к массиву $_POST заменяются обращениями к массиву $_REQUEST. При этом если LSB Навигатор ожидает получить некоторый параметр методом POST, то он не использует параметр с таким же именем, но получаемый методом GET. Это позволяет гарантировать, что при описанном изменении метода передачи параметров коллизий не возникает и функциональность приложения не нарушается.

В процессе генерации перебираются имена параметров, извлеченные из текста скрипта. Для каждого параметра перебираются значения из множества, формируемого следующим образом:

  • если значение параметра сравнивалось в тексте скрипта с некоторой константой, то такая константа заносится во множество возможных значений параметра. Так, для параметра 'cmd' перебираются все значения, найденные в соответствующих предложениях 'case';

  • если имя параметра совпадает с именем поля в одной из таблиц спецификационной базы данных LSB, то во множество потенциальных значений заносятся следующие значения:

    • значение, которое содержится в соответствующем поле хотя бы одной записи базы данных;

    • значение-строка, которое гарантированно не встречается ни в одной записи базы данных;

    • значение-число, которое гарантированно не встречается ни в одной записи базы; такое значение заносится в список только для полей БД числового типа. Для определения такого значения из существующих значений выбирается максимальное и к нему прибавляется единица. При этом производится проверка, что полученное число умещается в диапазон значений поля; если это не так, будет выдано предупреждение (однако автоматический выбор нового значения в настоящее время не реализован, поскольку в реальной базе данных таких ситуаций пока не возникает). Стоит отметить, что правила именования полей в базе данных LSB позволяют отличить поля, имеющие числовой тип, от полей текстового типа, на основе самого имени;

  • есть несколько параметров, для которых все возможные значения задаются вручную.

Поскольку количество скриптов и их параметров велико, то перебор всех возможных сочетаний значений параметров нецелесообразен. В целях уменьшения количества тестов применяются различные стратегии перебора комбинаций параметров — на данный момент генератор может быть настроен на использование каждого второго из всех возможных сочетаний, каждого третьего, и т.д. Недостатком на данный момент является то, что одна и та же стратегия перебора применяется ко всем комбинациям параметров; если для каких-то параметров необходимо применить другую стратегию, то необходима ручная правка генератора тестов. В будущем планируется сделать генератор более удобным в настройке.

5.3. Вынесение вердикта

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

В качестве СУБД в Linux Foundation используется MySQL, для работы с ней из Навигатора используются соответствующие функции PHP. В соответствии с описанным ранее подходом, непосредственно из скриптов вызываются функции-обертки, производящие обращение к реальным функциям и первичную обработку возвращаемых результатов. Так, при получении ошибки от MySQL функции-обертки выводят на генерируемую страницу фразу 'MySQL ERROR', за которой следует непосредственно текст ошибки. Эти функция — единственный потенциальный источник фразы 'MySQL ERROR' на странице; при нормальном функционировании приложения она не может возникнуть, поэтому ее появление в тексте свидетельствует об ошибке.

Каждая получаемая в процессе тестирования страница проверяется на соответствие стандарту XHTML 1.0. Для проверки соответствия страницы стандарту XHTML используется Offline HTMLHelp.com Validator [13].

Также после выполнения производится анализ логов HTTP-сервера (в случае LSB Навигатора — Apache), из которого выбираются предупреждения и ошибки, выдаваемые интерпретатором PHP.

В будущем планируется расширить анализ текста страниц HTML, генерируемых приложением в процессе тестирования. Например, на данный момент встречаются ошибки, связанные с некорректным формированием ссылок из страницы на другие части документа. В случае LSB Навигатора можно утверждать, что если ссылка содержит обращение к скрипту, передавая ему некоторые параметры, но при этом часть параметров имеет пустое значение, то такая ссылка некорректна — перейдя по ней, пользователь получит сообщение о некорректном значении параметров. Поиск таких ссылок в документе является достаточно простой задачей.

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

5.4. Результаты

Автоматические тесты для LSB Навигатора позволили к настоящему времени выявить около 30 ошибок, связанных с функциональностью. При этом общее число ошибок, занесенных в базу ошибок Навигатора за время его разработки — 250. Кроме того, автоматические тесты играют роль регрессионных и позволяют следить за тем, что генерируемые приложением страницы соответствуют стандарту XHTML; выполнение этой работы вручную нереалистично из-за сложности приложения и его базы данных. Разработка же анализатора скриптов и генератора тестов заняла 2 человеко-дня.

Характеристики генерируемых тестовых наборов по состоянию на декабрь 2007 года приведены в Таблице 1. Тесты делятся на две категории, в соответствии с режимом работы LSB Навигатора, для которого они предназначены. LSB Навигатор предоставляет два режима работы — режим пользователя (“Browse mode”) и режим администратора (“Administration mode”). При работе в режиме пользователя не допускается никаких изменений в базе данных (т.е. осуществляются только выборки данных при помощи оператора SELECT), в то время как в режиме администратора предоставляется практически полный контроль над базой данных. Скрипты, реализующие режим администратора, могут осуществлять гораздо больше различных запросов к базе данных и принимают на вход значительно большее число параметров. Ввиду этого тестирование работы в режиме администратора занимает больше времени, чем в случае режима пользователя.

Режим работы

Количество тестов

Время генерации

Время тестирования

Пользователь

2912

15 с

1ч. 30 мин.

Администратор

28740

10 мин.

6 ч. 15 мин.

Таблица 1. Характеристики тестовых наборов для режимов пользователя и администратора LSB Навигатора.

Число тестов для режима администратора превосходит число тестов для режима пользователя в примерно 10 раз, а время их генерации — в 40. Это обусловлено тем, что при генерации тестов для режима администратора анализатор кода использует существенно больше системных ресурсов, что, в частности, приводит к активному использованию swap-раздела. В то же время затраты на выполнение тестов для этого режима отличаются не столь сильно; этот факт объясняется тем, что любой запрос, выполняемый в режиме администратора, затрагивает только одну таблицу базы данных (более того, существенная часть запросов обращается только к одной записи таблицы). В режиме же пользователя выполняется много сложных агрегатных запросов, выбирающих данные сразу из нескольких таблиц (например, при сборе различных статистических данных).

Большую часть времени (порядка 80%) занимает проверка получаемых страниц на соответствие спецификации XHTML. Соответственно, отключение этой проверки позволяет за то же время сгенерировать и выполнить большее количество тестов (например, перебирая больше различных комбинаций параметров). Более того, время анализа результатов тестирования сильно зависит от числа выявляемых при такой проверке ошибок (что обусловлено особенностями используемого для проверки инструмента) — так, наличие ошибок, проявляющихся в 250 тестах для режима пользователя (8% от общего количества) привело к увеличению времени их выполнения до 8 часов.

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

  • Вывод имен классов, типов и шаблонов без преобразования угловых скобок, знака ‘&’ и других специальных символов (на страницах, содержащих декларации функций и классов C++), которые могут быть интерпретируемых Web-браузером как часть разметки страницы, а не как данные. Такие ошибки выявляются в процессе проверки страницы на соответствие спецификации XHTML.

  • Ошибки, связанные с экранированием символов в строках, используемых в запросах к базам данных. Отсутствие экранирования приводит к некорректности запроса SQL и получению ошибки при работе с СУБД. Обнаружение таких ошибок чрезвычайно важно, т.к. их наличие в приложении делает потенциально возможным использование SQL-инъекций — способа взлома сайтов и программ, работающих с базами данных, основанного на внедрении в запрос произвольного SQL-кода [16].

  • Ошибки, связанные с некорректной обработкой переданных параметров. При определенных значениях параметров на их основе может быть создан некорректный SQL-запрос, что приведет к ошибке взаимодействия с СУБД.

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

Измерение покрытия кода показало, что в процессе тестирования покрывается 60% строк кода скриптов (как уже упоминалось ранее, всего скрипты содержат около 17000 строк кода). Для сравнения — если просто обратиться к каждому скрипту без передачи ему каких-либо параметров, то покрытие составит 15%. Для измерения покрытия используется свободный инструмент PHPCoverage компании Spike Source [17]. Стоит отметить, что анализ покрытия кода также помогает выявлять недостижимый код, удаление которого приводит к увеличению покрытия.

Несмотря на достаточно высокое значение тестового покрытия, в процессе ручного тестирования встречаются ошибки, которые потенциально могли быть выявлены и автоматическими тестами (как правило, это ошибки работы с базой данных, либо ошибки формирования страницы, приводящие к нарушению спецификации XHTML). Такие ошибки проявляются на специфических значениях параметров при определенном их сочетании; они не выявляются автоматически, поскольку в процессе генерации тестов перебираются не все сочетания значений параметров. Как уже отмечалось ранее, генератор тестов обладает некоторыми средствами настройки стратегий перебора параметров, эти средства осуществляют достаточно грубую настройку. В результате при задании достаточно жестких ограничений на комбинации параметров тесты пропускают некоторые ошибки, а даже незначительное ослабление этих ограничений приводит к слишком большому количеству тестов, выполнение которых может длиться больше недели. Поэтому возможность более тонкой настройки генератора является одним из приоритетных направлений развития в ближайшем будущем; также возможно, что уменьшению числа тестов без потери качества может помочь более глубокий анализ зависимостей между параметрами.

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

6. Заключение

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

В то же время большинство современных средств тестирования Web-приложений используют в своей работе сценарии, создаваемые людьми; полноценное тестирование больших приложений с применением такого подхода требует больших людских ресурсов. Также ресурсоемким оказывается создание и поддержание в актуальном состоянии набора регрессионных тестов. Причем для приложений, у которых содержательная часть одной и той же страницы постоянно меняется, возможность создания сложных тестовых сценариев сомнительна - ведь страницы, генерируемые при создании сценария, не могут быть использованы в качестве эталонов при вынесении вердикта об успешности прохождения теста. В таких случаях приходится применять менее строгие проверки, чем сравнение страниц с эталоном целиком. Однако создание тестов и выполнение ряда несложных проверок может быть автоматизировано, что позволяет существенно экономить ручной труд. В то же время даже достаточно простые проверки могут помочь выявить серьезные ошибки.

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

Предлагаемый подход к генерации тестов на основе исходного кода приложения гораздо больше зависит от структуры кода. Впрочем, эта структура не налагает ограничений на саму возможность применения метода; однако именно от нее зависит сложность реализации метода для конкретного приложения. Соответствие кода некоторым условиям может существенно упростить создание тестов и в тоже время сделать их более качественными. Конкретные формулировки таких условий зависят от используемого языка программирования (более точно — от способа доступа к параметрам, передаваемым приложению, который предоставляет язык); в статье приводятся формулировки для приложений, написанных на PHP.

Такие условия могут быть учтены при создании приложения. При их соблюдении для анализа кода не требуется полноценного парсера используемого языка программирования; достаточным оказывается создание существенно более простого инструмента. Примером приложения, для которого предлагаемый подход позволяет получать достаточно качественные тестовые наборы за короткое время, является LSB Навигатор (распространяющийся по лицензии GPL; исходный код может быть получен в соответствующем разделе Linux Foundation Bazaar [18]). Естественно, реализация метода зависит от языка программирования, на котором написано приложение. Однако для многих скриптовых языков, используемых при создании Web-приложений, сложность реализации этого подхода примерно одинакова; ключевым фактором все-таки является структура исходного кода.

Литература

  1. XHTML 1.0. The Extensible HyperText Markup Language (Second Edition).
  2. Википедия — свободная энциклопедия. Скриптовый язык.
  3. IBM Rational Robot.
  4. HP WinRunner Software.
  5. Empirix e-TEST suite.
  6. PureTest — Users Guide. Minq Software, 2006.
  7. eValid Web Testing & Analysis Suite.
  8. Web Application Testing with Puffin.
  9. С. Рогов, Д. Намиот. Тестирование производительности Web-серверов. Открытые системы, 12:55–64, 2002.
  10. А. А. Сортов, А. В. Хорошилов. Функциональное тестирование Web-приложений на основе технологии UniTESK. Труды ИСП РАН, 8(1):77–97.
  11. RFC 2616. Hypertext Transfer Protocol — HTTP/1.1.
  12. Jmeter User's Manual. Jakarta Project, 2007.
  13. Offline HTMLHelp.com Validator.
  14. LSB Navigator.
  15. LSB Specification Database.
  16. Википедия — свободная энциклопедия. Инъекция SQL.
  17. Spike PHPCoverage.
  18. Linux Foundation Bazaar — DB Navigator module.

Назад Содержание

Новости мира IT:

Архив новостей

Последние комментарии:

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 985 1945361
Пресс-релизы — pr@citforum.ru
Обратная связь
Информация для авторов
Rambler's Top100 TopList liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2015 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...