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

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

.
Эвристики ХРОНИЧеского регрессионного тестирования
21.04.2010 00:02

Автор: Карен Н. Джонсон (Karen N. Johnson)

Перевод: Дмитрий Дудников по заказу Software-Testing.RU

Оригинальная публикация

Регрессионное тестирование порой может быть весьма трудоёмкой задачей. Регрессионное тестирование – это тестирование, предназначенное для повторной проверки свойств приложения или продукта с целью убедиться в том, что после внесения изменений или добавления новых возможностей приложение по-прежнему работает. Уже из определения видно, что регрессионное тестирование может быть очень обширным, поскольку может потребоваться повторная проверка практически каждого свойства продукта. Как правило, регрессионные тесты – это тесты, разработанные ранее, следовательно, основная работа при регрессионном тестировании заключается не столько в создании тестов, сколько в их выполнении. Таким образом, самая первая проблема – это планирование того, что мы будем перепроверять. Итак, как же выбрать, что подвергнуть регрессионному тестированию?

Чтобы не забыть те аспекты, которые следует принять во внимание при планировании регрессионного тестирования, я придумала эвристику, состоящую из шести частей:

Недавнее (Recent)

Основное (Core)

Рисковое (Risky)

Чувствительное к конфигурации (Configuration sensitive)

Исправленное (Repaired)

Хроническое (Chronic)

Эвристика – это практический экономичный способ, помогающий нам решить проблему и/или вынести суждение. Эвристика – несовершенный метод. Цель данной эвристики – помочь рассмотреть различные аспекты приложения, которое вы тестируете, всесторонне обдумать его и подсказать или обнаружить области для регрессионного тестирования.

Для запоминания этой эвристики можно использовать аббревиатуру, состоящую из первых букв – НОРЧИХ (в оригинале RCRCRC: Recent-Core-Risky-Configuration sensitive-Repaired-Chronic). Но ещё проще её запомнить, если переставить буквы в другом порядке: ХРОНИЧ, потому что одна из целей регрессионного тестирования – борьба с хроническими проблемами, это одна из составных частей эвристики. Так что если вы запомните её, вы легко вспомните и все остальные. А порядок частей не так уж важен, лишь бы при планировании регрессионного тестирования вы учли их все, ничего не забыв.

Недавнее (Recent)

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

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

Спросите себя: «что мы делали недавно?». Нарисуйте диаграмму или выпишите список. Одна из причин, по которой я особенно люблю начинать с этого вопроса, состоит в том, что на ум приходят именно те изменения, которые несут самые большие риски. Я начинаю со списка интуитивно понятных критичных вещей, а затем проверяю остальные моменты, пополняя список. Среди прочего не забудьте проанализировать запросы на изменение требований, сообщения об ошибках, изменения модели данных (я спрашиваю о них в особенности, чтобы быть в курсе изменений на серверной стороне) и, конечно же, относящуюся к делу внутреннюю переписку.

Основное (Core)

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

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

Рисковое (Risk)

Как правило, нетрудно вспомнить области повышенного риска, имеющиеся в приложении – будь то новые функциональные возможности или старые. Эти опасные места приходят на ум без особых подсказок. Какие именно функциональные возможности? Возьмите, к примеру, функции, зависящие от других сервисов или компонентов, которые должны быть запущены и работать. Если вы тестируете веб-сайт с защищенными страницами, на месте ли сертификаты? Если вы знаете, где были проблемы в прошлом, вам будет легче определить области риска в настоящем. Используйте вашу систему контроля ошибок для акцентирования внимания на тех областях продукта, которые в прошлом имели больше всего проблем. Также как и перечень ключевых функций продукта, список опасных мест должен быть относительно коротким.

Чувствительное к конфигурации (Configuration sensitive)

Одна из банальностей, которую я обнаружила в тестировании, такова: код, который зависит от параметров окружения, т.е. чувствительный к конфигурации, более уязвим. Код, зависящий от тонкой настройки параметров, похож на ошибки копирования и вставки, которые мы делаем в документах. Мы думаем, что нашли все ссылки и обновили данные, но ничего не стоит пропустить лишь одну ссылку и вуаля! – мы получили ошибку. Генерируемые и отсылаемые от имени приложения почтовые сообщения – частый пример кода, зависящего от окружения или требующего корректных изменений настроек для правильного функционирования. Учет таких особенностей приложения помогает принимать решения о необходимости повторного тестирования конкретных функциональных возможностей – и о том, в каком окружении необходимо это делать.

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

Исправленное (Repaired)

Тестировщики иногда спорят – как часто должен перетестироваться дефект? Если ошибка исправлена и повторно протестирована, должна ли она проверяться в следующих релизах? В какой момент можно сказать, что дефект был перетестирован достаточное количество раз, чтобы более не проверять его?

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

Хроническое (Chronic)

У каждого из нас, людей, есть свои слабости – физические и/или умственные. Приложения тоже имеют свои слабые места. Некоторые области продукта, кажется, преследует закон Мёрфи: если что-то может сломаться, оно обязательно сломается. Одна из причин, по которым я люблю долго работать с одним продуктом – это более глубокое понимание его болячек. Чем дольше я работаю с продуктом, тем больше я знаю о том, где проблемы были, где они есть сейчас, и где их можно ждать в будущем. Другое преимущество длительной работы с продуктом – это скорость, с которой я могу проверить все проблемные точки для получения уверенности в его качестве.

Спросите себя, нет ли у продукта свойств, в которых вы не слишком уверены? Нет ли у продукта областей, в которых часто возникают проблемы? Не будет ли полезным провести еще несколько регрессионных тестов?

Резюме

Имея в руках диаграмму функциональных возможностей продукта или контрольный список, вы готовы начать. Регрессионное тестирование вероятнее всего не обнаружит новых проблем, поэтому мы можете быстро пройти весь список, даже если он выглядит достаточно длинным. Самое лучшее планирование регрессионных тестов произрастает из хорошего знания приложения, но для того, чтобы избежать шаблонного тестирования одних и тех же областей и пропуска других, я использую эвристику ХРОНИЧеского тестирования, помогающую мне окинуть взглядом всю картину. А затем, в конце тестирования, я выписываю другой список: того, что осталось НЕ протестировано. Этот список помогает мне в случаях, когда кто-то спрашивает: «протестирована ли функция Х?» С его помощью я учитываю те вещи, которые было решено не тестировать. И порой, просматривая этот список, я понимаю, где я хочу потратить еще несколько минут, где я хочу провести еще один, последний тест, прежде чем я, наконец, скажу: «всё готово!»

Обсудить в форуме