Вторая статья из серии Кирпичики будет посвящена полезным, на мой взгляд, процессам.
SCRUM
Суть методологии SCRUM настолько проста и бесхитростна, что всю теорию можно изучить за пару часов, прочитав пару статей. Всё становится интереснее, когда это знание пытаются применить на практике. Судя по общению с коллегами из разных контор, ВСЕ так или иначе адаптируют его под себя и частенько до такой степени, что от оригинала остается мало. Но тем не менее итеративная модель разработки, построенная на идеях командной, работы имеет большие плюсы. Последние годы мы с небольшими вариациями используем следующий процесс:
- У нас есть бэклог, в который мы стараемся заносить все наши планы и так или иначе его приоритезировать и оценивать.
- Мы используем 2х недельные итерации.
- В начале итерации (спринта) разбиваем истории на задачки и вешаем их на доску вида STORY\TASKS\IN PROGRESS\REVIEW\DONE.
- Каждый день проводим короткие standup'ы.
Одним из очевидных плюсов всего этого является вовлеченность команды во все аспекты разработки. Но увы многие, умудренные опытом разработчики занимают позицию в стиле "вы мне скажите что сделать - я сделаю" и пытаются самоустраниться из процесса принятия решений.
РОЛЬ PRODUCT OWNER'а
В SCRUM-процессе одна из основных ролей это роль Product Owner'а. Без человека, который понимает, что он хочет, и готов инвестировать в это приличное время, работать не получается. К сожалению, в больших продуктовых компаниях формальным Product Owner'ом является Product Manager, на котором висит несколько проектов и куча бюрократии. Надеяться на то, что он будет детально прорабатывать истории и вникать в детали, не приходится. Хорошо, если он может в общих чертах описать проблему и ожидаемый результат. Опыт использования разного рода аналитиков, проксирующих через себя функции Product Owner'а, в моей практике оказалась не очень удачным. Для себя я сделал вывод, что менеджер проекта сам должен взять на себя функцию прокси между командой и настоящим product owner'ом и вести продукт опираясь на мнение Product Managment'а, stackholder'ов и команды. Ну это при условии, что ему не все равно, что будет на выходе. :)
Definition of Done
При работе в команде важно, чтобы у всех было единое понимание готовности той или иной части. Очень часто бывает, что разработчик считает свой код рабочим, если ему удается его просто собрать.
Мы применяем достаточно простой чеклист:
- Фича собрана на CI сервере.
- Код должен пройти Code Review командой.
- Код покрыт unit тестами.
- Все тесты зеленые.
- Фичу посмотрели члены команды в тестовой лабе.
- Нет ошибок\варнингов.
- Нет серьезных замечании со стороны статических анализаторов кода.
Мы живем в реальном мире и, конечно же, часть пунктов этого списка часто нарушается, но при этом всем немного стыдно. :)
BACKLOG
Backlog и его ведение должно быть как можно проще, в противном случае на его поддержку быстро начнут забивать. Актуальный бэклог с простым механизмом оценки и приоритетов может сослужить хорошую службу и позволит не забыть что-то важное. Я использую PivotalTracker - он очень прост, и в этом его прелесть. Легко написать историю, оценить ее, изменить приоритет и поменять состояние.
По бэклогу мы строим burndown chart, который с некой долей вероятности показывает нам насколько далеки мы от релиза. Надо понимать, что backlog постоянно изменяется и дополняется, потому на графике неизбежны всплески и провалы.
SPRINT BURNDOWN CHART
При планировании спринта истории разбиваются на конкретные задачки и вешаются на доску. В процессе спринта они постепенно переходят в состояние Done. График этого процесса достаточно интересен. По росту количества незапланированной работы можно понять насколько хорошо мы планируем спринт, а по общему количеству часов понять, сколько стоит брать в следующий раз. Не стоит особо париться, если окажется, что средняя скорость члена команды будет около 2х часов в день. Важно, чтобы эта цифра постепенно увеличивалась или, как минимум, не уменьшалась. Вообще, метрики в SCRUM - это не повод помахать шашкой, а лишь повод задуматься.
CODE REVIEW
Ревью кода членами команды - одна из полезнейших практик. И самое главное в этом даже не поиск ошибок, их как раз выявляют на этом этапе достаточно редко. Главное это то, что в процессе ревью с кодом знакомятся остальные члены команды. Это ведет к расширению области знании как в конкретной технологии, так и в продукте в целом. Мы для ревью кода используем механизм pull request'ов GitHub'а. При этом ревьюятся не отдельные коммиты, а законченная функциональность или существенная ее часть. В этом нам помогает модель gitflow, где на каждую новую фичу создается отдельная ветка.
Мне кажется более правильной модель, когда ревьюер кода не назначается, а код смотрит как можно большее число членов команды. Совместное владение кодом ведет к улучшению состояния этого кода.
SOURCE CONTROL
Активная фаза разработки требует наличия системы контроля версии. Я начинал с CVS, прошел SVN, StarTeam, Mercurial и остановился на git. В основу этого выбора легла статья "A successful Git branching model". На мой взгляд, подход, позволяющий независимо разрабатывать фичи продукта и постоянно иметь рабочую ветку, готовую к поставке, повышает качество и снижает напряженность при возникновении непредвиденных трудностей в процессе разработки фичи. Последнее время наша команда придерживается следующих простых правил.
- Бренч master содержит результаты итерации в виде squash'ных коммитов (по одному на итерацию), в комментарии которого максимально подробно описывают все, что было сделано по каждой фиче, и по сути являются ChangeLog'ом.
- Бренч dev - завершенные фичи текущей итерации. Каждый коммит - завершенная фича с комментариями максимально подробно ее описывающими.
- Бренчи для фичи могут содержать любые коммиты.
В основном я доволен этим подходом. Меня немного огорчает тот факт, что при использовании --squash теряется информация об исходных коммитах, а без использования squash в ветках dev и master появляется огромное число мелких коммитов с малоинформативными сообщениями, что затрудняет понимание истории разработки.
Так же к достоинствам git хочу отнести очень демократичный набор инструментов. В нашей команде есть люди использующие как консоль, так и разные оконные клиенты.
Continues Integration
Я уже не могу себе представить, как можно вести разработку, не имея Continues Integration, в задачи которого входит быстрая сборка последней версии, сборка всяких артефактов типа MSI\CD, прогон тестов и установка на тестовые машины. Причем основная причина такой любви к CI это банальная лень. Да, мне совершенно не хочется тратить время на сборку, установку и проверку базовой работоспособности новой версии вручную. Пусть это делает компьютер. За те 3-10 минут, которые идет процесс сборки, я лучше посмотрю в окно или почитаю почту.
Я прошел длинный путь в сборке проектов, начав с nmake и bat, пройдя через скрипты на Visual Build, прежде чем пришел к готовым CI серверам.
Попробовав за 6 лет CruiseControl.NET, Hudson, Jenkins и TeamCity , я остановился именно на последнем. Прежде всего TC поставляется из коробки с кучей полезных вещей, которые к Jenkins надо еще прикручивать, ко всему прочему я полностью укладываюсь в бесплатные рамки TeamCity.
Еще один из аспектов CI серверов, к котором я пришел: их инфраструктура должна быть как можно проще. В идеале, помимо самого агента TeamCity я бы хотел видеть там только Visual Studio (если без нее никак). Чем билдер проще, тем легче добавлять агентов и восстанавливать его после падений.
Спасибо за внимание.