Сегодня я хотел бы затронуть очень интересное и новое понятие – “задолженность по дефектам” (bug debt). Много разговоров ведется про другой вид задолженности – “техническую задолженность” (technical debt). Но они обе очень важны. Понимание этих терминов увеличивает шансы проекта на успех.
Дефекты в коде появляются по разным причинам: недопонимание требований, несовершенство технических инструментов, невнимательность или спешка, недостаток опыта или технических навыков, и так далее. Дефекты пагубно влияют на работу всей команды. Прежде всего, они требуют времени тестировщиков на нахождение, анализ и описание. Причем, так как чаще всего тестировщики работают через пользовательский интерфейс, а не напрямую с источником проблем (программным кодом), то затраченное время увеличивается в разы. Также, по мере нахождения, дефекты нужно исправлять. Этот процесс требует вовлечения разработчиков, которые тратят время на анализ, исправление и дополнительные активности по проверке и предотвращению дефекта в будущем. На этом все не заканчивается – тестировщикам необходимо проверить исправленный дефект и внести изменения в различные системы (система управления дефектами, система хранения тестовых сценариев и другие). Таким образом, каждый дефект стоит команде очень дорого. И чем позже он будет найден и исправлен, тем выше стоимость.
У дефектов есть еще одно интересное свойство. Если система не покрыта “сетью безопасности” в виде автоматизированных тестов, то исправление одних дефектов часто приводит к порождению других. И образуется замкнутый круг. Все больше и больше дефектов скапливается в системе, на их исправление не отводится времени, потому что нужно разрабатывать новую функциональность. Некоторые дефекты живут в системе очень давно и превращаются в ограничения. Благодаря таким ограничениям, разработчикам приходится идти на хитрости и во многих случаях вставлять костыли. Труднее всего тестировщикам, потому что им приходится анализировать зависимости между дефектами, расставлять приоритеты и мириться с их существованием. Мотивация всей команды падает и многие начинают поговаривать о полном переписывании системы.
В то же время, наличие открытых дефектов запускает в действие принцип “разбитых окон”. Никто не задумывается при добавлении в систему очередного сомнительного кода – ведь и так уже куча дефектов. Этот же принцип распространяется и на архитектурные решения. И системе становится все хуже и хуже… А мы еще не коснулись таких проблем как наличие стабильной сборки системы, блокирующих дефектов, недовольство заказчика и конечных пользователей, а также многих других.
Agile принципы говорят нам о том, что продукт должен быть рабочим и именно это есть главная метрика прогресса. Одно из основных преимуществ Agile подходов – это предсказуемость. Но наличие дефектов сводит предсказуемость на нет, потому что найденные дефекты нужно исправлять, что сильно влияет на продуктивность команды, а значит и на результаты для заказчика. Как следствие, теряется доверие и начинает разваливаться процесс разработки.
Что же делать чтобы не допустить всего описанного? Главная задача – сфокусироваться на качестве кода, на предотвращении дефектов. Для этого, конечно же, тоже понадобится время. Начать можно с автоматизации сборки системы, потому что без этого шага тяжело будет выполнить другие. На рынке существует огромное количество инструментов для решения этой задачи (Ant, Maven, NAnt, MSBuild, Gradle и другие), выберите подходящий и вперед.
Вторым шагом является подключение и настройка статических анализаторов кода. Они помогут вам избежать многих ошибок, а также предоставят детальную статистику по состоянию вашего кода. Большая часть из таких анализаторов (FxCop, FindBugs, PMD, Sonar, JSLint и другие) очень просто установить и начать использовать. Я рекомендую изначально включать все возможные проверки, а по мере использования отключать или настраивать те, которые вам не подошли. Делать это нужно осознанно и централизованно, а не просто скрывать имеющиеся проблемы. Важным шагом является настройка работы с результатами анализа в IDE, так как это упрощает работу разработчиков.
Дальше необходимо позаботиться о том, чтобы сборки и анализ кода проходили регулярно и как можно чаще. Для этого вам понадобится Continuous Integration сервер. На данный момент существует множество бесплатных и платных решений (TeamCity, Bamboo, Hudson, CruiseControl и другие), есть из чего выбирать. На установку и начальную настройку у вас не уйдет много времени. По ходу использования вы расширите настройки, подключите необходимые модули и установите дополнительные приложения.
Теперь можно переходить к следующему шагу – созданию “сети безопасности”. Начните писать модульные и интеграционные тесты. Лучший способ начать – это обязательно писать их для нового кода, а также для кода, в котором найден дефект или проводится изменение. Не стоит торопиться, добиться полного покрытия всего кода быстро вам не удастся. Так что нужно запастись терпением. Помните главное правило бойскаутов: “Когда вы покидаете место привала, вы должны постараться хоть как-то улучшить его”. Точно также поступайте со своим кодом – старайтесь при каждом изменении хотя бы немного его улучшить. Тогда вы будете медленно и уверенно двигаться в сторону улучшения всего кода системы.
Следующий шаг направлен на контроль выполнения предыдущих шагов и поиск новых улучшений. Этот шаг предполагает внедрение практики Code Review. Эта практика помогает убедиться в том, что все необходимые действия над кодом выполнены успешно и он соответствует стандартам, принятым на проекте. Для того, чтобы внедрить эту практику, вам необходимо обсудить и принять список требований к коду (критерии готовности). Такой список должен составляться с участием всех членов команды. Пункты списка подлежат обязательному контролю, постарайтесь изменить процесс управления задачами так, чтобы было невозможно миновать стадию Code Review.
Теперь, когда вы приложили массу усилий для того, чтобы избежать дефектов, осталось совсем немного. Необходимо уменьшить цикл обработки дефекта. Для этого требуется уменьшить все циклы обратной связи. Тестировщики могут давать обратную связь на завершенные части работы разработчиков, как только они готовы. Размер итерации стоит сделать как можно меньше, чтобы заказчик мог давать обратную связь по законченной функциональности. Должно измениться отношение к дефектам. Дефект на свежую функциональность, найденный в итерации, должен быть исправлен как можно быстрее. Для этого можно использовать визуальные инструменты, чтобы избежать траты времени на “официальное” проведение дефекта через все системы контроля. Это не означает, что системы контроля не нужны. В конце итерации открытые дефекты обязательно заносятся в них, чтобы ими можно было управлять наряду с другими задачами. Для еще большей экономии времени стоит поменять коммуникационный протокол, используемый для дефектов. При нахождении нового дефекта тестировщик может записывать автоматизированный сценарий с помощью инструментов тестирования (TestComplete, QTP, Selenium, Watir и другие). Этот тест заменит разработчику многострочное описание дефекта и ускорит его работу. Описание же добавится по необходимости, если дефект не удастся быстро исправить.
Вот и все. Было не так уж трудно? Теперь ваши тестировщики начинают меньше времени тратить на дефекты, у них появляется время на тестирование методом свободного поиска, нахождение потенциальных улучшений для продукта, другие виды тестирования. Разработчики не занимаются бесконечными сессиями по исправлению дефектов, они занимаются реализацией новой функциональности. Ваш процесс разработки предсказуем и заказчики знают когда и что могут ожидать от вашей команды. Вы все довольны своими успехами и пользователи благодарны вам за продукт, в котором практически нет дефектов. Это миф? Нереально? А вы попробуйте…
Спасибо большое, поправил. 🙂
всё-так debt, а не dept
Да, не всегда просто. Но, если все понимают для чего все это нужно и как работает, то тогда достаточно просто. При должном уровне контроля. 😉
Хорошая статья. Описаны вроде бы очевидные вещи, но именно их многие не знают или не понимают.
Не согласен только с тем, что “Было не так уж трудно?” 🙂 на практике разработка и поддержка такого “проектного фреймворка” требует усилий, внимания.. и поддержки всей команды (слово всей подчеркнуто :))