Цена ошибки: как экономия приводит к повышенным тратам
Когда мы обсуждаем вопрос создания программного обеспечения, то говорим не только про архитектуру, технологии, навыки, но и про экономику. Абсолютно все проекты требуют бюджета, и он не может быть бесконечным. Необходимость рационального использования средств очевидна всем, а про необоснованную экономию порой умалчивают. А зря, ведь это в конечном итоге приводит к повышенным тратам.
Экономия затрагивает самые разные сферы проекта и специалистов. В этой статье рассмотрим обеспечение качества (QA). Бизнес нередко считает, что тестирование – та часть проекта, на которой можно сэкономить, что за качество должны отвечать разработчики, а QA-специалистов иногда можно и не привлекать. Мы постараемся на конкретных примерах показать, к каким последствиям приводят наиболее популярные случаи экономии на QA.
Вариант 1. Отсутствие тестирования на ранних этапах
Начнем с классического случая экономии на проекте – отсутствия тестирования на ранних этапах жизненного цикла ПО.
Первоначальная выгода от такого решения кажется очевидной – пока не накопилось достаточного объема кода для тестирования, подключение QA-специалистов некритично. Однако оправданность такого решения при детальном рассмотрении оказывается сомнительной.
Многие слышали фразу «Чем раньше найден баг, тем проще и дешевле его исправить», давайте разберемся, почему это так и насколько дешевле. Поскольку баги появляются в фичах, представим упрощенный жизненный цикл фичи, который существует в большинстве проектов:
- Идея
- Написание технического задания (далее – ТЗ)
- Реализация
- Тестирование
- Выход в релиз
Обратите внимание, что на этой схеме QA подключаются довольно поздно – на этапе тестирования. Используя этот алгоритм, легко вычислить, что:
- Если в фиче нет дефектов, то каждый участник жизненного цикла затрачивает свое время 1 раз, таким образом разработка стоит 5 условных часов.
- Если баг допущен на этапе реализации и найден на этапе тестирования, то разработчик и QA затрачивают по одной дополнительной единице времени: на фикс бага и на повторное тестирование (ретест) исправленной фичи, соответственно. В итоге получается: 5+2=7 единиц времени. У вас может возникнуть вопрос, почему мы считаем 5 часов, а не 4, если после тестирования фича не пошла в релиз? Потому что после исправлений и повторного тестирования все равно наступает релиз.
- Если баг допущен на этапе написания ТЗ и найден на этапе тестирования, то единиц времени будет 8 (5+3 на: исправление ТЗ, фикс бага , ретест)
- Если баг допущен в самой идее фичи и выявлен на этапе тестирования, то будет затрачено 9 единиц времени (5+4 на: коррекцию идеи, исправление ТЗ, фикс бага, ретест исправлений)
Теперь давайте представим, что QA подключается на более раннем этапе – между написанием ТЗ и разработкой – и тестирует требования. В этом случае баги можно будет выявить раньше и сэкономить время.
Тестирование постановок (ТЗ) – одно из популярных решений тренда на раннее тестирование или, как это называют некоторые компании, «shift left».
В третьем и четвертом случаях это будет 1 и 2 единицы времени соответственно. Однако можно заметить, что в первом и втором случаях происходит увеличение затрачиваемого времени на 1 единицу. Где же выгода? Добавим в теоретическую модель данные о статистике возникновения дефектов и реально затрачиваемом времени на тестирование требований и исправления постановок и кода.
Начнем с возникновения дефектов. Мы собрали статистику со 117 проектов в различных сферах и анализ показал, что 66 % багов возникают на этапе реализации (написания кода), 31% - на этапе постановки задачи и 3% дефектов содержатся в идеях фич.
Возникает вопрос: «А как же интеграционные баги?» Фича рассматривается как самостоятельная сущность, а интеграционный баг – это либо проблема внешнего сервиса и ее не решить силами команды, либо фича неправильно взаимодействует с исправным внешним компонентом.
Представим, что ваше приложение взаимодействует с внешним сервисом файлового хранилища, которое в один момент перестало отвечать. Соответственно, в самом приложении сломаются все функции, которые связаны с внешним файл-сервером. Это и будет интеграционным багом.
Переходим ко времени, которое затрачивается на тестирование требований.
Практика показывает, что тестирование требований на одну фичу (именно требований, а не фич) в среднем занимает от 25 минут до 6 часов. Значения более 2,5 часов встречаются крайне редко, а 4 и более часа ревью свидетельствуют о том, что фича перегружена требованиями и ей требуется декомпозиция.
Теперь рассмотрим время, затрачиваемое на корректировку ТЗ.
Исправления ТЗ занимают от 10 минут в случае мелких опечаток до 9-10 часов, если нужна серьезная переработка логики, получение дополнительной информации, созвоны, согласования, ожидание ответов и т.д.
И наконец, изучим распределение времени, которое тратится на исправление кода.
На фиксы дефектов в коде уходит от 20 минут до 8 часов, в зависимости от сложности багов и если при исправлении не возникает критических противоречий с существующим кодом, стенды работоспособны, а ТЗ достаточное для работы.
Анализ диаграмм позволяет сделать несколько выводов:
- Весомая доля (около 31%) дефектов зарождается на этапе создания ТЗ
- Типичное время тестирования ТЗ меньше, чем типичное время исправления кода (багофикса)
Обогащение модели жизненного цикла фичи реальными данными было бы не полным без сравнения затрат времени на реализацию. Однако, тут прикладывать какие бы то ни было диаграммы распределения времени сложно, поскольку информация получена с разных проектов, где фичи сильно различаются по размеру и трудоемкости. Значит, без объяснения, что делалось при реализации задачи, трудно понять затраты времени на нее. Более показательна статистика с проектов, где внедрили тестирование требований, как один из вариантов тестирования на ранних этапах разработки.
На графике видно, что среднее время жизненного цикла фичи снизилось на величину от полутора до семи часов. Такая экономия времени происходит не только благодаря внедрению раннего тестирования, но и оптимизации его применения. То есть в реальности, даже с учетом того что в постановке изъянов может не быть, тестирование ТЗ все равно оправдывает себя за счет того что в случае наличия таких дефектов, они выявляются до стадии реализации, при этом сохраненное время, больше затраченного.
Например, на тестирование требований не обязательно подключаться всем QA команды. Это могут делать отдельные сотрудники. Кроме того, в результате проверки требований часто происходят мелкие правки ТЗ, которые делают его более понятным и однозначным, что в итоге сокращает время, которое уходит на вопросы и пояснения при разработке.
Вариант 2. Тестирование силами разработчика
Довольно популярный способ сэкономить на проекте. Но, как показывает практика, мнимая экономия на часах QA-специалистов может обернуться серьезными потерями от исправления пропущенных багов и замедлением работы. Да и в целом является экономически невыгодной. Далее расскажем подробнее.
Тестирование ПО возникло практически одновременно с появлением софта для компьютеров. Изначально оно было исчерпывающим. При таком тестировании перебирались все возможные входные параметры программы. Занимались этим сами разработчики. Однако усложнение ПО сделало исчерпывающее тестирование слишком долгим, а в итоге и невозможным. Вследствие этого от специалистов понадобились специальные навыки, которыми не обладали разработчики. Так появились профессиональные тестировщики.
Разработчик может заниматься тестированием, только он будет это делать не слишком эффективно, поскольку он не специализируется на этом виде деятельности.
Наши QA-специалисты нередко подключаются на проекты, где не было тестирования как процесса, выполняемого отдельными людьми. Приемочный аудит таких проектов показывает, что отношение количества багов критичности major и выше к общему количеству фичей составляет 26,4 %.
Критичность «major» означает значительную ошибку, при которой часть основной бизнес-логики работает некорректно.
После подключения профессиональных QA этот процент сокращается до 1,3 %. Небольшой процент сохраняется, так как в выборке присутствуют проекты, где допустимо выкатывать релизы с определенным количеством major багов.
Еще один аргумент против тестирования силами разработчика – экономическая нецелесообразность. Пока он тестирует, процесс создания новых фич стоит на месте. А если принять во внимание стоимость рабочего часа, то вывод напрашивается сам собой: использовать разработчиков для полноценного тестирования ПО – дорого, медленно и малоэффективно. При этом мы еще не учитываем упущенную выгоду из-за пользователей, которые обнаружили пропущенные дефекты в продукте и отказались от его использования, репутационные потери и прочее.
Вариант 3. Отказ от регресса
Регрессионное тестирование (далее – регресс) – проверка ранее протестированного ПО или его отдельных компонентов, которая позволяет удостовериться, что последние внесенные изменения не повлекли за собой появления дефектов в неизмененной части программы.
Важная особенность регресса – в его регулярности. При этом может возникнуть вопрос: зачем тестировать то, что уже протестировано? Это непонимание впоследствии перерождается в отказ от проведения регрессионного тестирования.
Необходимость и польза его проведения становится очевидной при детальном изучении жизненного цикла ПО.
Практически все современные проекты после выхода в релиз к пользователю продолжают развиваться: наполняться новыми функциями, переезжать на более современные технологии, оптимизироваться и т.п. Кроме того, приложения часто зависят от «внешней среды» стороннего ПО, которое тоже меняется, и не про все изменения вы можете знать.
Эти изменения, как правило, проводятся в локализованных компонентах системы и прямо влияют только на них. Тестирование изменений включает в себя стандартный набор из функциональных и нефункциональных тестов. Однако из-за сложности современных приложений корректировки в одном компоненте могут вызвать проблемы в других. И тут, конечно, можно сказать, что такие баги должно выявлять интеграционное тестирование, но часто влияние изменений не всегда очевидно.
Интеграционное тестирование предназначено для проверки связей между компонентами ПО, а также взаимодействия со сторонними программами. При этом функциональность продукта, которую пользователь ожидает видеть исправным, не должна пострадать.
Для таких случаев и существует регресс. Он позволяет убедиться, что незатронутые изменениями части ПО или всё в целом работает корректно. О важности проведения регресса говорит статистика возникновения регрессионных багов – ошибок, которые возникли в результате изменений в смежном функционале.
Для исследования мы выбрали 46 проектов, каждый из которых был выпущен в релиз и просуществовал не менее полугода.
Выборка также позволила вычислить коэффициент количества регрессионных багов в зависимости от размера проекта. При расчетах за единицу было взято количество регрессионных багов на небольшом проекте.
Анализ частоты возникновения регрессионных дефектов позволяет выделить два факта:
- Появление регрессионных дефектов с развитием проекта неизбежно.
- Чем сложнее и крупнее проект, тем больше вероятность появления регрессионных багов.
Но при этом нельзя забывать о рациональном подходе к любым процессам. Очевидно, что при регулярных прогонах полного списка тест-кейсов затраты на регресс едва ли будут себя оправдывать. Поэтому для повышения эффективности применяют различные способы оптимизации, например, логичным способом снижения затрат является автоматизация регресс-тестов.
Кроме технических решений, разумно применять оптимизацию процессов тестирования и разделять регрессы по количеству производимых проверок на:
— крупные, которые будут проводится после изменений в ключевых компонентах,
— средние – в зависимости от серьезности внесенных изменений,
— мелкие, прогоняемые после каждого изменения в ПО.
При микросервисной архитектуре проекта регрессы можно разделить по функциональным компонентам и проводить тестирование только тех модулей IT-системы, которые связаны с измененной частью.
Таким образом, проведение регрессионного тестирования – необходимый процесс в современной разработке приложений, который позволяет предотвратить встречу пользователя с дефектами. Грамотная оптимизация этого процесса помогает существенно сократить затраты при сохранении общей эффективности.
Вариант 4. Отказ от тестовой документации
Тестовая документация – совокупность документов, которые создаются перед началом тестирования, а в некоторых случаях и в процессе. Она описывает покрытие требований тестами, а также процесс выполнения проверки ПО. В документации указывается вся информация, необходимая для тестирования. С точки зрения процессов она используется для структурирования работы QA.
Тестовая документация бывает низкоуровневая, в которой описаны непосредственно проверки (тест-кейсы, тест-сьюты, чек-листы и т.д.) и высокоуровневая – с описанием процесса тестирования, необходимых ресурсов, критериев завершения тестирования и требований к качеству релиза. Все это позволяет повысить вероятность отсутствия дефектов и предоставления качественного ПО для конечных пользователей.
Разумеется, создание тестовой документации требует времени, на котором часто экономят. Бытует мнение, что тестовая документация – это неоправданная трата времени и можно тестировать ПО без нее. Такое суждение складывается из-за непонимания последствий её отсутствия и неумения применять оптимальные виды документации в зависимости от особенностей проекта.
Начнем с первого. Тестовая документация позволяет планомерно, обстоятельно и полноценно оценить смысл и масштабы проверяемого функционала и покрыть его тестами. Её отсутствие не позволяет понять полную картину проекта и необходимого объема проверок. Без четких целей, пошагового плана их достижения и указания всех важных условий ожидаемый результат не будет ясен. В таких случаях велика вероятность забыть важные проверки и пропустить критичные баги.
Это особенно актуально при работе со сложными продуктами или часто меняющихся требованиях.
Теперь поговорим о рациональном применении различных видов тестовой документации. Практика показывает, что наибольшие затраты времени уходят на написание низкоуровневой документации, в частности, тест-кейсов.
Тест-кейс – своего рода «инструкция» по проверке узкой части функционала в определенных условиях. Этот вид документации содержит пошаговое описание проверки и формулировку ожидаемого поведения системы в данных условиях. Тест-кейсы удобны, понятны и подробны, они позволяют добиться минимальной вероятности пропуска дефектов. Но при этом создавать их долго, ведь для качественной проверки одной фичи могут потребоваться десятки тест-кейсов.
Этот вид документации оправдывает себя, если тестируемая функциональность сложна и наполнена неочевидной логикой или для проведения теста нужна определенная совокупность условий, которую необходимо строго выполнить.
Есть и менее трудозатратные виды тестовой документации, например, чек-лист. Он не содержит шаги, а ожидаемый результат поведения функции сформулирован в самом названии проверки. По сути, это список того, какие входные условия и выходные параметры нужно проверить в фиче. Чек-листы быстры в написании и актуализации, позволяют добиться должного уровня покрытия тестами и уверенности в отсутствии дефектов. Но минусы тоже есть. Поскольку шаги воспроизведения проверок не записаны явно и фактически хранятся в памяти специалиста, эффективно пользоваться чек-листом может только написавший его человек.
Документация позволяет фиксировать результаты тестирования, что позволяет получить данные об объеме пройденных проверок и различные показатели по найденным багам. То есть открывается возможность собирать метрики о качестве продукта, управлять развитием проекта и более эффективно вносить улучшения.
Исходя из вышесказанного, тестовая документация – не пустая трата времени, а инвестиция в качество проекта. Грамотное применение различных видов тестовой документации и их комбинаций оправдывает затраты и позволяет минимизировать риск попадания к пользователю дефектного ПО.
Вместо вывода
Подводя общий итог, хочу еще раз подчеркнуть, что рациональное использование бюджета проекта – важная задача, которая требует навыков планирования, прогнозирования и опыта. Без планирования работы команды и прогнозирования последствий управленческих решений, экономия получается сиюминутная, и зачастую она приводит к проблемам или повышенным расходам на поздних этапах жизни проекта. А без опыта работы не будет понимания причин и следствий проблем, а также примеров успешных решений.