Как стать автором
Обновить
1123.59
OTUS
Цифровые навыки от ведущих экспертов

Регрессионная спираль смерти

Время на прочтение11 мин
Количество просмотров7.2K
Автор оригинала: Blake Norrish

Перевод статьи подготовлен в преддверии старта курса «Автоматизация тестирования на JavaScript»





История, которая может показаться вам до боли знакомой:


Вы работаете QA в небольшой команде разработчиков; сегодня утро четверга второй недели вашего двухнедельного спринта. У вашей команды еще несколько историй (story) в разработке, которые должны быть утверждены к утру пятницы, чтобы быть готовыми к демонстрации днем. Ваши планы на вечер четверга начинают таять на ваших глазах.


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


«ОК», — говорит скрам мастер, — «как насчет…», и вы точно знаете, что будет дальше. «…как насчет того, чтобы мы передвинули автоматизацию на следующий спринт?» Автоматизация, стоящая непосредственно перед отметкой «выполнено», заложенная в историю и всегда занимающая часть оцененного времени, выталкивается в будущее. В очередной раз. «Мне это тоже не нравится…», — говорит ваш скрам-мастер, видя выражение вашего лица, — «…но сейчас наша скорость на виду, это очень важно, поскольку мы приближаемся к этому гигантскому майлстоуну — мы просто не можем не добить наши стори поинты».


«Я понимаю», — отвечаете вы с улыбкой, чтобы продемонстрировать, что вы командный игрок и тоже стремитесь к тому, чтобы команда выглядела так, как будто она успешно справляется.


Конец истории


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


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


Регрессионное тестирование


Прежде чем мы перейдем к регрессионной спирали смерти, мы должны понять идею регрессионного тестирования, и в частности, что тестирование фичи — это больше, чем просто тестирование фичи.


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


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


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


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


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


Agile Delivery и бремя регрессии


Agile Delivery вводит две концепции, относящиеся к регрессионной спирали смерти. Во-первых, Agile Delivery делит фичи на небольшие, отдельные пользовательские истории (user stories). Каждая пользовательская история должна быть атомарной, чтобы ее можно было разрабатывать и тестировать как отдельный объект. Во-вторых, Agile Delivery способствует коротким циклам разработки с небольшими итеративными релизами. Все виды и гибриды Agile, Scrum, Kanban, SAFE, LeSS, ScrumBan и т. д. по-своему используют эти концепции. Давайте посмотрим на каждую в отдельности.


Agile Delivery отходит от использования больших функций, определенных (даже более крупными) документами спецификаций, к пользовательским историям, каждая из которых представляет собой небольшую часть общего объема работ. Истории Agile независимо разрабатываются, тестируются, ревьюятся и утверждаются.


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



История 13 была внедрена и протестирована. Нам не о чем беспокоиться?
/ НЕТ! Изменения в коде могли повлиять на другие истории (как связанные, так и не связанные с этой историей)


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


Давайте перейдем ко второй концепции — что Agile Delivery поощряет небольшую, инкрементную доставку. Если бы необходимо было регрессировать приложение каждые шесть месяцев, стоимость регрессионного тестирования, даже медленного ручного, не была бы ощутимой. Фактически, именно так мы раньше и поставляли программное обеспечение до перехода к Agile разработке — у нас был бы план регрессионного тестирования, и каждые шесть месяцев мы выполняли этот план перед релизом. Это часто занимало дни или недели, но в рамках шестимесячного цикла релиза это было не слишком обременительно.


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


Давайте рассмотрим простой гипотетический набор спринтов, чтобы прояснить, насколько быстро стоимость регрессии может отягощать скорость команды.


Предположим, у нас есть недавно созданная Agile-команда, которая только начинает свою первую итерацию разработки (спринт). На первой итерации (или некоторой начальной продолжительности в потоковой модели) у нас может быть три истории для тестирования. Тестирование этих историй довольно простое — мы просто тестируем эти три истории. Во второй итерации мы добавляем две дополнительные истории. Сколько усилий будет затрачено на тестирование этих историй? Наивный ответ «несколько меньше усилий, чем для первого спринта», так как мы тестируем только две истории. Однако, основываясь на нашем понимании того, что изменения кода могут вызвать регрессию в любой области приложения, мы знаем, что мы должны протестировать обе новые истории, а также регрессировать три ранее завершенные истории.



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


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


Если мы экстраполируем этот шаблон на множество спринтов, мы увидим, что в модели Agile-разработки с ручной регрессией стоимость регрессии ранее завершенных историй быстро затмевает стоимость тестирования новых историй — количество ранее завершенных историй накапливается в каждом спринте, и весь набор должен быть регрессирован на каждой итерации.



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


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



Автоматизация в Agile Delivery


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


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


Важно понимать, что автоматизация тестирования не ускоряет первоначальное тестирование. На самом деле, внедрение автоматизации тестирования часто замедляет базовую скорость разработки. Автоматизация — это процесс разработки, который требует продумывания и опыта, как и всё остальное! Автоматизация не тестирует — это просто запрограммированная проверка того, что уже было протестировано. К счастью, это именно то, что нам нужно для смягчения регрессионной спирали смерти!


Если учесть моменты двух предыдущих разделов — то, что изменения в программном обеспечении могут иметь непреднамеренные последствия, и что agile delivery — это просто непрерывный поток небольших изменений — становится очевидным, что agile delivery не может функционировать без автоматизации тестирования. Попытка итеративной доставки без него — это все равно, что отправиться в дальнюю дорогу, но отказаться от остановок, потому что остановки замедляют вас. Топливо — фундаментальная часть автомобильного путешествия (на данный момент), так же, как автоматизация тестирования — фундаментальная часть Agile Delivery. Автоматизация — это единственное, что может смягчить удушающее бремя регрессии и избежать резкого падения скорости разработки.



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


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


Я твердо убежден в том, что без полной автоматизации тестирования не может быть здоровой Agile Delivery. Полная автоматизация историй с набором средств автоматизации, охватывающим все виды тестов (модуль, компонент, интеграция, пользовательский интерфейс и т. д.), абсолютно необходима для поддержания скорости доставки на протяжении всего жизненного цикла. Любое предложение о послаблении этого требования для каждой истории следует отвергать и объяснять, что это такое — краткосрочное отвлечение для создания восприятия успеха, в то же время ставящее под угрозу долгосрочные цели развития. Не говоря уже о здравом уме.


Спираль смерти


Вернемся к нашей маленькой истории.


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


Вы собираетесь протестовать, когда ваш скрам-мастер вмешивается: «Мы не можем этого сделать! Это первый шаг к регрессионной спирали смерти!»


«Автоматизация всегда является частью определения готовности», добавляет разработчик, «это часть продукта, как код, ориентированный на клиента».


«Вы хотите, чтобы мы преуспели или просто казались преуспевающими?» Эти слова вашего бизнес-аналитика, вызывает улыбку на вашем лице.


Вы решаете отменить собеседование на следующей неделе.


Слова благодарности


Я не изобрел термин «регрессионная спираль смерти», но никогда не видел его в письменной форме. Самое раннее использование термина, которое я могу найти, находится в «Тестировании экстремального программирования» (2002) Лизы Криспин и Тип Хаус.


Несколько других ссылок можно найти с помощью быстрого поиска в Google:


http://ivory.idyll.org/blog/software-quality-death-spiral.html (2008)


https://xebia.com/blog/regression-testing-with-an-agile-mindset (2010)




Узнать всё о курсе «Автоматизация тестирования на JavaScript»



Теги:
Хабы:
Всего голосов 12: ↑10 и ↓2+9
Комментарии3

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS