пятница, 20 августа 2010 г.

Практика непрерывной интеграции

Непрерывная интеграция (continuous integration) в разработке ПО означает процесс непрерывного применения контроля качества. Целью является повышение качества ПО и уменьшение времени на реализацию процедур по повышения качества.

В основе своей содержит понятие сборки и регулярную проверку различных метрик кода.
Я использую (в порядке внедрения в проект) в проектах на java:
* Компилируемость кода. Весь код должен компилироваться. Всегда. Избавляет от вопросов "Сейчас в svn неработающий код, что мне делать?" и заявлений "Я не хочу обновляться, так как наверняка там код неработающий"
* Отсутствие замечаний Findbugs. Тут случай, когда машина работает за человека и отлавливает множество глупых ошибок по невнимательности. Классическая и самая у нас часто встречаемая: появление неиспользуемых переменных. Обычно означает, что написали часть кода, вычислили значение и забыли его использовать. У Findbugs бывают ложные срабатывания, но их не так много если использовать только определенные проверки
* Прохождение junit тестов. Наличие тестов позволяет разработчикам быстрее принимать решение по внесению изменений. Они их просто делают и смотрят, не сломались ли тесты. Практика показывает, что нереально выполнять все тесты на машине разработчика. Лучше иметь единое место, где гарантированно выполняться все тесты. Также количество тестов должно расти.
* Процент покрытия кода тестами. Плюс в том, что можно вести 1 число, и его сможет отслеживать кто угодно, даже не разработчик. Минус в том, что обосновать это число (у нас 75%) невозможно, и отдача наступает через долгие месяцы. Но наступает.
* Отсутствие комментариев TODO. Придерживаюсь правила, что в норме в коде не должно быть TODO. Нормально, если они появляются во время итерации, но затем должны быть безжалостно изведены под 0, либо фактическим исправлением, либо фиксацией issue в багтрекере либо в честном признании, что его никогда не исправят и его удалении. Видел проект с тысячами TODO, уже с неприличными комментариями к ним, которые никто не исправлял, они только расстраивают разработчиков.

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


Преимущества
* Раннее обнаружение ошибок. Многие разработчики мне часто говорят "Я не помню, что делал вчера, мне надо посмотреть историю изменений". В в проектах с внедренной непрерывной интеграции применительно к ошибкам сборки они этого не говорят, так как время обнаружения от 3 минут до 1 часа. Никто не хочет сознаваться, что не помнит, что делал 5 минут назад
* Если настройка проекта сложная, то не надо запускать и настраивать среду разработки под проект. Прямо в системе непрерывной интеграции можно смотреть изменения, так как они маленькие, то просто догадаться, что надо исправить и кому следует исправить.
* Эталонная работающая система сборки. Если вы принимаете решение выкатывать релиз заказчику вы не потратите неделю на то, чтобы систему собрать. Для нас актуально, так как система сборки для разработчиков и для деплоя различается.
* Возможность тестирования в различных окружениях и конфигурациях. У разработчика настроена 1 конфигурация, на сервере непрерывной интеграции их несколько.
* Можно автоматически создавать техническую документацию по проекту (javadoc, отчет по используемым библиотекам, по покрытию тестами, по замечаниям Findbugs и т.д.)
* Метрики подключаются достаточно быстро, бывают достаточно 5 минут (например столько ушло на включение в проект проверки на количества TODO)

Недостатки
* Надо потратить время на внедрение системы непрерывной интеграции, подбор инструментария. Практика показала, что на первое внедрение могут быть затрачены недели, на следующее всего пара дней.
* Нужен человек, которому надо, чтобы система непрерывной интеграции работало. Все соглашаются, что неработающий код - это плохо, но ничего не делают. На практике люди самостоятельно начинают исправлять замечания через порядка 1 год использования системы
* Нужен выделенный сервер. Из хорошего - это может быть дохлая машина с 1-2 Гб памяти.

Инструменты (в порядке внедрения)
* скрипты на bash, python + ant
* Hudson + ant
* Hudson + maven

Примерные сроки и затраты на внедрение
* Проверка компилируемости. Скрипт + cron + email. Примерно неделя. С удивлением обнаружил, что часть модулей не компилируется, какие-то починены, какие-то отправлены в архив. Несколько месяцев на внедрение в сознание разработчиков мысли, что код должен компилироваться всегда, а не только в момент сборки для клиента
* Проверка findbugs. В проекте было порядка 3000 замечаний. Примерно неделя ушло на встраивание ant задачи проверки и неделя на зачистку замечаний. После этого год жили с проверкой компилируемости и замечаний findbugs, реализовано на скриптах
* Hudson. Неделя на настройку. Дал историю сборок, хранение логов сборки и доступ через http. Позволил не запускать GUI оболочку Findbugs для нахождения места с замечанием.
* Junit. Примерно календарный месяц ушел на изучение литературы по шаблонам тестирования xUnit, на написание первых десятков тестов, на встраивание вызова тестов на стенд и визуализацию результатов в Hudson. При этом потрачено порядка 2 недель времени.
* Покрытие кода тестами с помощью Cobertura. Ушло календарных 2 недели. Одна сборка c участием Cobertura занимала десятки минут, отладка настройки шла ужасно долго. Потрачено реально пара дней. Позволила искать места, не покрытые тестами.
* Использование maven. За несколько дней был настроен maven проект со все необходимым. Попутно получили возможность создания документации по проекту, оставили лишь нужные отчеты.
* По моей экспертной оценке в начале внедрения надо тратить порядка 0.5-1 ч в день ведущему разработчику, чтобы устранять замечания или искать виноватого. Попутно он лучше узнает код других. В дальнейшем ошибок становиться меньше и люди исправляют замечания самостоятельно.

среда, 18 августа 2010 г.

Внедрение scrum для аналитиков

Испробовав scrum, ты начинаешь его применять везде.

Особенности аналитиков
1. Результат их работы часто не представляет самостоятельной ценности, пока это не реализовано разработчиком. Можно считать, что разработка является этапом тестирования для постановки. Поэтому возникает классическая проблема отставания тестирования при классическом подходе к разработке: сначала пишутся постановки, потом они оцениваются, потом они планируются и лишь потом выполняются. Безусловно эти проблемы могут нивелироваться опытом аналитика.
2. Все встреченные мной аналитики - индивидуалисты. Разработчиков объединяет язык программирования, используемые технологии. У аналитиков из инструментов Word и Visio, у них больше свободы и им тяжелее работать вместе. Придуманы нотации, UML, IDEF0, но аналитик их не может полноценно использовать, пока заказчики не начнут использовать эти нотации. А делать правильные описания в правильных нотациях и одновременно иметь классические текстовые постановки не хотят.
3. У разработчиков есть понятие парного программирования, у аналитиков оно отсутствует как класс.
4. Любой может выполнять роль аналитика, плохо или хорошо. Но я не встретил еще аналитика, который может выполнить роль разработчика, пусть даже плохо.
5. Про разработчиков говорят "выделяйте как можно больше непрерывного времени". Аналитики говорят "я должен начать писать одну постановку, не закончить ее переключиться на другую. Затем вернуться к первой, взглянуть на нее свежим взглядом и т.д."

Особенности внедрения scrum для аналитиков
1. Критерий Done.
Надо с ним договориться, что постановка не сделана, если ее не прочитал другой член команды. Без этого невозможно определить, что постановка закончена.И договориться, что вообще-то постановка будет считаться сделанной, если по ней что-то реализовали.
2. Первый месяц заставить жить себя без оценок. Аналитики их давать не любят. Обходиться лишь приоритетами, причем по "мягкой схеме", несколько задач одного приоритета. В дальнейшем все равно начинать требовать оценок.
3. Просить идти аналитиков от меньшего к большему в постановках.
Если аналитик закладывает в постановку много требований, то разработка начинает запаздывать и реализуется не все. Часть переносится на следующую итерацию или вообще "на потом". Постановку тогда надо изменять, чтобы она соответствовала реализации. Лучше, если бы постановка была меньше, потом на изменения написали бы отдельную постановку.
4. Позволять аналитикам делать несколько задач. Но от итерации к итерации изменять это значения и смотреть на его влиянии на фокус-фактор.
5. Попросить начинать постановку с формирования плоского приоритезированного списка User Story. После определения, какие User Story все же реализуем, указывать How to demo. Затем лишь писать собственно постановку и, в идеале, Test cases.

Внедрение scrum в командах разработчиков

Мой опыт внедрения scrum в командах разработчика.

Процесс внедрения
1. Посадить людей вместе.
Люди не любят перемен. Даже если это перемены к лучшему. Простая задача - рассадить 5 существующих команд в одной большой комнате, чтобы каждая команда была вместе - очевидно полезное решение. Люди будут меньше мешать друг другу. Но в процессе перестановке получили часть недовольных изменениями. Через некоторое время (2 недели) люди оценили плюсы и согласились, что так лучше. Еще пара изменений составов команд и перемещений по комнате прошли уже достаточно гладко.
2. Купить доску.
В большой организации это, оказывается, проблема. Купил доску и позже выбил с организации деньги. Для команды из 2 человек хватает доски 60 на 90 см. Для команды 5 человек нужна доска 90*180 см. У одних команд были пробковые доски, у других пластиковые магнитные с возможностью на них писать. Лучше всего 2 доски - 1 для крепления задач, другая для рисования на ней.
3. Выделить роли в команде.
Определить, кто является членом команды, кто product owner, кто заказчиком. Что делать, если несколько product owner - найти главного product owner.
4. Составить плоский список задач.
Все любят создавать сложные иерархии работ. Так логичнее, есть логика и т.д. Но создать простой плоский список работ - непривычный опыт.
5. Product owner расставляет приоритеты
Вначале команда не сработана, никто не кому не доверяет. Product owner ставит разные приоритеты у задач, жестко определяя порядок. Через некоторое время (2-3 месяца) Product owner начинает доверять команды и ставить у нескольких задач одинаковый приоритет, доверяя команде в определении последовательности
6. Оценка работа командой
Product owner присутствует, но желательно поменьше вмешиваться. Можно использовать карты для оценки, можно нет, работает оба варианта, надо пробовать, что лучше для вашей команды.
7. После оценки приоритеты могут изменяться
8. Стартуем итерацию.
9. Понимаем, что нужны критерии Test, WIP, Test, Done. Пишем и печатаем на доску. Понимаем, что в задачах нужен критерий How to demo: не берем в план, если не описано.
10. По окончании итерации считаем фокус фактор как отношение суммы первоначальных оценок задач в Done к общему рабочему времени команды.
11. Проводим ретроспективу.
Первые 2 месяца все жалуются на бытовые условия. После надо начинать фиксировать проблемы в процессах и в технологиях.
12. Планируем 2 итерацию, уже есть фокус фактор, можем оценить, сколько задач выполним.
Фокус фактор стабилизируется через 3 недели совместной работы над одинаковыми задачами.
13. Дотачиваем процесс
Уточняем критерии Plan, WIP, Test, Done. Регулярно добиваемся работы по приоритетам. Добиваемся фиксации технического лога и регулярное включение его в итерацию. Увеличиваем размер команды.

Результаты
У нас были недельные итерации.
По моему опыту шаги 1-12 занимают минимум 3 - 12 недель.
Чтобы внедрение успешно прошло, внедряющий scrum должен первые 2 недели быть в команде. Затем периодически следить за изменением фокус фактора.
В результате фокус фактор стабилизировался на отметке 40-70%.
Непривычным оказалось, что неважно, в чем оценивать задачи: в днях, часах, идеальных днях. С помощью фокус фактора это все переводится в часы.
Чтобы все это работало Product Owner должен понять, что если он хочет добавить что-то, то он должен убрать что-то. Если он будет давить на команду, то команда сделает то, что он просит, но не сделает что-то другое и scrum позволяет это видеть до завершения итерации.
Важно - не делать лишнего. Если что-то в пределах не требует фиксации в электронном виде - не фиксируйте. Клейте листочки, но не фиксируйте. Но когда итерация закончена, все оставшееся надо зафиксировать.