Scrum и xp заметки с передовой
Скачать 3.07 Mb.
|
Плохо: Понедельник 09-10 Спринт №1: демо 10-11 Спринт №1: ретроспектива 13-16 Спринт №2: планирование Перед началом нового спринта (если быть точным, после ретроспективы спринта и перед планированием следующего спринта) мы стараемся добавлять небольшой промежуток свободного времени. Увы, у нас это не всегда получается. Как минимум, мы стараемся добиться того, чтобы ретроспектива спринта и следующее планирование спринта не проходили в один и тот же день. Перед началом нового спринта каждый должен хорошенько выспаться, не думая при этом о спринтах. Лучше: Понедельник 09-10 Спринт №1: демо 10-11 Спринт №1: ретроспектива Вторник 09-13 Спринт №2: планирование Еще лучше: Scrum и XP: заметки с передовой 55 Суббота Воскресение Пятница Понедельник 09-10 Спринт №1: демо 10-11 Спринт №1: ретроспектива 09-13 Спринт №2: планирование Один из вариантов для этого – "инженерные дни" (или как бы вы их не называли). Это дни, когда разработчикам разрешается делать по сути все, что они хотят. (ОК, я признаю, в этом виноват Google). Например, читать о последних средствах разработки и API, готовиться к сертификации, обсуждать компьютерные занудства с коллегами, заниматься своим личным проектом, ... Наша цель – инженерный день между каждым спринтом. Так между спринтами появляется реальная возможность отдохнуть, а команда разработки получает хороший шанс поддерживать актуальность своих знаний. К тому же, это достаточно весомое преимущество работы в компании. Лучше некуда? Суббота Воскресение Понедельник 09-13 Спринт №2: планирование Пятница Инженерный день Четверг 09-10 Спринт №1: демо 10-11 Спринт №1: ретроспектива Сейчас у нас один инженерный день между спринтами. Если конкретно, то это первая пятница каждого месяца. Почему же не между спринтами? Ну, потому что я считал важным, чтобы вся компания брала инженерный день в одно и то же время. Иначе люди не воспринимают его серьезно. И так как мы (пока что) не согласовывали спринты между всеми продуктами, я был вынужден выбрать инженерный день, независимый от спринтов. Когда-нибудь мы можем попробовать согласовать спринты между продуктами (то есть одна и та же дата для начала спринта и одновременное окончание спринтов для всех продуктов и команд). В этом случае, мы точно поместим инженерный день между спринтами. Scrum и XP: заметки с передовой 56 12 Как мы планируем релизы и составляем контракты с фиксированной стоимостью Иногда нужно планировать дальше, чем на один спринт вперед. Это типичная ситуация для контрактов с фиксированной стоимостью, когда нам приходится планировать наперед, или же есть риск подписаться под нереальной датой поставки. Как правило, планирование релиза для нас – это попытка ответить на вопрос: "когда, в самом худшем случае, мы сможем поставить версию 1.0". Если вы действительно хотите разобраться, как планировать релиз, советую пропустить эту главу и купить книгу Майка Кона "Agile Estimating and Planning". Эх, прочитать бы мне эту книгу раньше... (она попалась мне уже после того, как мы на собственном опыте поняли, что к чему...). Мой способ планирования простой, как угол дома, но может послужить вам хорошей отправной точкой. Определяем свою приёмочную шкалу В дополнении к обычному product backlog'у, product owner определяет приёмочную шкалу, которая представляет собой ни что иное, как простое разбиение всех историй product backlog'а на группы в зависимости от их уровня важности в контексте контрактных обязательств. Вот пример диапазонов из нашей приёмочной шкалы: • Все элементы с важностью >= 100 обязаны быть включены в версию 1.0, иначе нас оштрафуют по полной программе. • Все элементы с важность 50-99 должны быть включены в версию 1.0, но в случае чего мы можем выкатить эту функциональность в следующем дополнительном релизе. • Элементы с важностью 25-49 необходимы, но могут быть сделаны в последующем релизе версии 1.1. • Важность элементов < 25 весьма спорна, так как возможно, что они вообще никогда не пригодятся. Вот пример product backlog'а, раскрашенного в соответствии с вышеописанными правилами: Важность Название 130 Банан 120 Яблоко 115 Апельсин 110 Гуава 100 Груша 95 Изюм 80 Арахис 70 Пончик 60 Лук 40 Грейпфрут 35 Папайя 10 Черника 10 Персик Scrum и XP: заметки с передовой 57 Красные = обязательно должны быть добавлены в версию 1.0 (банан – груша) Жёлтые = желательно включить в версию 1.0 (изюм – лук) Зелёные = могут быть добавлены позже (грейпфрут – персик) Итак, если к крайнему сроку мы закончим всё: от банана до лука, то нам бояться нечего. Если время будет нас поджимать, то мы ещё успеем выкрутиться, убрав изюм, арахис, пончик и лук. Всё, что ниже лука – бонус. Оцениваем наиболее важные истории Чтобы спланировать релиз, product owner'у нужны оценки, как минимум оценки всех включенных в контракт историй. Как и в случае планирования спринта, это – коллективный труд команды и product owner'а. Команда планирует, а product owner объясняет и отвечает на вопросы. Оценка считается ценной, если впоследствии она оказалась близкой к реальности. Менее полезной, если отклонение составило, скажем, 30%. И абсолютно бесполезной, если она не имеет ничего общего с реально потраченным временем. А вот что я думаю о зависимости ценности оценки от того, кто и как долго её делает. Время, потраченное на оценку Ценность оценки Командная оценка Оценка product owner’а Резюмируя вышесказанное: • Пусть команда проведёт оценку. • Не давайте им тратить на это много времени. • Убедитесь, что команда понимает, что нужно получить приблизительные оценки, а не контракт, под которым надо ставить подпись. Обычно product owner собирает всю команду, делает вводный обзор и сообщает, что целью этого совещания является оценка двадцати (например) наиболее значимых историй из product backlog'а. Он проходится по каждой истории и позволяет команде приступить к процессу оценки. Product owner остаётся с командой, чтобы, в случае необходимости, отвечать на вопросы и прояснить объём работ историй. Так же, как и при планировании спринта, колонка "как продемонстрировать" – отличное средство, чтобы избежать недопонимания. Совещание должно быть строго ограниченным по времени – команды склонны тратить очень много времени на оценку всего нескольких историй. Если product owner захочет потратить больше времени на оценку, он просто назначит другое совещание позже. Команда должна убедиться в том, что product owner осознаёт, что проведение подобных совещаний отразится на их текущем спринте. То есть, что он понимает, что за все (и за оценку в том числе) нужно платить. Ниже приведен пример результатов оценки (в story point'ах): Scrum и XP: заметки с передовой 58 Важность Название Оценка 130 Банан 12 120 Яблоко 9 115 Апельсин 20 110 Гуава 8 100 Груша 20 95 Изюм 12 80 Арахис 10 70 Пончик 8 60 Лук 10 40 Грейпфрут 14 35 Папайя 4 10 Черника 10 Персик Прогнозируем производительность Хорошо, теперь у нас есть приблизительные оценки для наиболее важных историй. Следующий шаг – прогноз средней производительности команды. Это значит, что для начала мы должны определить наш фокус-фактор (см. стр. 23 "Как команда принимает решение о том, какие истории включать в спринт?") По большому счёту, фокус-фактор показывает: "насколько эффективно команда использует своё время для работы над выбранными историями". Это значение никогда не достигнет 100%, так как команда всегда тратит время на незапланированные задачи, помощь другим командам, переключение между задачами, проверку электронной почты, ремонт своих поломанных компьютеров, политические дебаты на кухне и т.д. Предположим, что фокус-фактор нашей команды равен 50% (это достаточно низкое значение, у моей команды значение колеблется в районе 70%). Допустим также, что длина нашего спринта будет 3 недели (15 дней), а размер команды – 6 человек. Таким образом, каждый спринт – это 90 человеко-дней, однако, в лучшем случае мы можем надеяться только на 45 человеко-дней (так как наш фокус-фактор составляет всего 50%). Следовательно, прогнозируемая производительность составит 45 story point'ов. Если у каждой истории оценка будет равна 5 дням (хотя такого и не бывает), тогда эта команда сможет выдавать на-гора примерно по 9 историй за спринт. Сводим всё в план релиза Сейчас, когда у нас есть оценки и прогнозируемая производительность, мы можем легко разбить product backlog на спринты: Scrum и XP: заметки с передовой 59 Важность Название Оценка Спринт 1 130 Банан 12 120 Яблоко 9 115 Апельсин 20 Спринт 2 110 Гуава 8 100 Груша 20 95 Изюм 12 Спринт 3 80 Арахис 10 70 Пончик 8 60 Лук 10 40 Грейпфрут 14 Спринт 4 35 Папайя 4 10 Черника 10 Персик Каждый спринт состоит из набора историй, количество которых не превышает спрогнозированную производительность 45. Теперь видно, что, скорее всего, нам потребуется 3 спринта для завершения всей обязательной и желательной функциональности. 3 спринта = 9 календарных недель = 2 календарных месяца. Станет ли это крайним сроком, который мы озвучим клиенту? Это полностью зависит от вида контракта, от того, насколько фиксирован объем работ, и т.д. Обычно мы берём время со значительным запасом, тем самым защищая себя от ошибочных оценок, возможных проблем, неоговоренного функционала и т.д. Значит, в этом случае мы установим срок поставки в 3 месяца, чтобы иметь месяц в резерве. Очень хорошо, что мы можем демонстрировать клиенту что-нибудь пригодное к использованию каждые 3 недели и позволять ему изменять требования на протяжении всего времени сотрудничества (конечно в зависимости от того, как выглядит контракт). Корректируем план релиза Реальность не подстроится под план, поэтому приходится его корректировать. По окончании спринта мы смотрим на реальную производительность команды. Если эта производительность существенно отличается от прогнозируемой, мы изменяем прогнозируемую производительность для будущих спринтов и обновляем план релиза. Если это грозит нам срывом срока поставки, product owner может начать переговоры с клиентом или начать искать путь уменьшения объема работ без нарушения контракта. Или, возможно, он и команда смогут увеличить производительность или фокус-фактор путём устранения серьёзных препятствий, которые были обнаружены во время спринта. Product owner может позвонить клиенту и сказать: "Привет, мы слегка не вписываемся в график, но я полагаю, что мы сможем уложиться в срок, если уберём встроенный Тетрис, разработка которого занимает много времени. Мы можем добавить его в следующем релизе, который будет через три недели после первого релиза". Пусть это и не самая лучшая новость, но, хотя бы, мы были честны и дали возможность клиенту заранее сделать выбор: или мы поставляем только самую важную функциональность в срок, или же всю полностью, но с задержкой. Обычно, это не очень сложный выбор. :o) Scrum и XP: заметки с передовой 60 13 Как мы сочетаем Scrum с XP То, что Scrum и XP (eXtreme Programming) могут быть эффективно объединены, не вызывает сомнений. Большинство рассуждений в интернете поддерживают это предположение, и я не хочу тратить время на дополнительные обоснования. Тем не менее, одну вещь я всё-таки должен упомянуть. Scrum решает вопросы управления и организации, тогда как XP специализируется на инженерных практиках. Вот почему эти две технологии хорошо работают вместе, дополняя друг друга. Тем самым я присоединяюсь к сторонникам мнения, что Scrum и XP могут быть эффективно объединены! Я собираюсь рассказать про наиболее полезные практики из XP и про то, как мы используем их в нашей повседневной работе. Не все наши команды смогли применить практики XP в полном объеме, но мы провели большое количество экспериментов со многими аспектами комбинации XP/Scrum. Некоторые практики XP напрямую соответствуют практикам Scrum, например, "Whole team", "Sit together", "Stories" и "Planning game". В этих случаях мы просто придерживаемся Scrum. Парное программирование Недавно мы начали практиковать его в одной из наших команд. Как ни удивительно, работает довольно- таки хорошо. Большинство других наших команд до сих пор не очень много программирует парно, однако, попробовав эту практику в одной из наших команд для нескольких спринтов, я вдохновился идеей внедрить парное программирование и в других командах. Вот пока несколько выводов после применения парного программирования: • Парное программирование действительно улучшает качество кода. • Парное программирование действительно увеличивает сосредоточенность команды (например, когда напарник говорит: “Слушай, а эта штуковина точно нужна для этого спринта?”) • Удивительно, но многие разработчики, которые выступают против парного программирования, на самом деле не практиковали его, однако раз попробовав – быстро понимают все преимущества. • Парное программирование выматывает, так что не стоит заниматься им целый день. • Частая смена пар даёт хороший результат. • Парное программирование действительно способствует распространению знаний внутри команды, заметно ускоряя этот процесс. • Некоторые люди чувствуют себя некомфортно, работая в парах. Не стоит избавляться от хорошего программиста, только потому, что ему не нравится парное программирование. • Ревью кода – хорошая альтернатива парному программированию. • У “штурмана” (человека, который не пишет код) должен также быть свой компьютер, но не для разработки, а для выполнения мелких задач, когда это необходимо – просмотра документации, если “водитель” (человек, который пишет код) запнулся и так далее. • Не навязывайте парное программирование людям. Вдохновите их, дайте необходимые инструменты и позвольте самим дойти до этого. Scrum и XP: заметки с передовой 61 Разработка через тестирование (TDD) Наконец-то! Разработка через тестирование для меня важнее, чем Scrum и XP вместе взятые. Можете отнять у меня дом, телевизор, собаку, но только попробуйте запретить использование TDD! Если вам не нравится TDD, тогда просто не подпускайте меня близко, иначе я всё равно привнесу его в проект втихую :) Курс TDD за 10 секунд: Разработка через тестирование означает, что вы сначала должны написать автоматизированный тест (который не проходит – прим. переводчика). После этого надо написать ровно столько кода, чтобы тест прошёл. Затем необходимо провести рефакторинг, в основном, чтобы улучшить читабельность кода и устранить дублирование. При необходимости повторить. Несколько фактов о TDD: • Разработка через тестирование – это непросто. На деле оказывается, что демонстрировать TDD программисту практически бесполезно – часто единственный действенный способ заразить его TDD заключается в следующем. Программиста надо обязать работать в паре с кем-то, кто в TDD хорош. Но как только программист вник в TDD, то он уже заражен серьезно и о разработке другим способом даже слышать не хочет. • TDD оказывает глубокое положительное влияние на дизайн системы. • Чтобы TDD стало приносить пользу в новом проекте, необходимо приложить немало усилий. Особенно много тратится на интеграционные тесты методом "черного ящика". Но эти усилия окупаются очень быстро. • Потрать достаточно времени, но сделай так, чтобы писать тесты было просто. То есть надо получить необходимый инструментарий, обучить персонал, обеспечить создание правильных вспомогательных и базовых классов и т.д. Мы используем следующие инструменты для разработки через тестирование: • jUnit / httpUnit / jWebUnit. Мы присматриваемся к TestNG и Selenium. • HSQLDB в качестве встроенной БД в памяти (in-memory) для тестовых целей. • Jetty в качестве встроенного web-контейнера в памяти (in-memory) для тестовых целей. • Cobertura для определения степени покрытия кода тестами. • Spring framework для написания различных типов тестовых фикстур (в т.ч. с использованием моков (mock-object) и без, с внешней БД и БД в памяти (in-memory) и т.д.) В наших наиболее сложных продуктах (с точки зрения TDD) у нас реализованы автоматизированные приёмочные тесты методом "черного ящика". Эти тесты загружают всю систему в память, включая базы данных и web-сервера, и взаимодействуют с системой только через внешние интерфейсы (например, через HTTP). Такой подход позволяет получить быстрые циклы "разработка-сборка-тест". Он так же выступает в качестве страховки, придавая разработчикам уверенность в успешности частого рефакторинга кода. В свою очередь, это обеспечивает простоту и элегантность дизайна даже в случае разрастания системы. TDD и новый код Мы используем TDD для всех новых проектов, даже если это означает, что фаза развёртывания рабочего окружения проекта потребует больше времени (потому что нужно больше усилий на настройку и поддержку тестовых утилит). Нетрудно понять, что выгода перевесит любой предлог не внедрять TDD. TDD и существующий код Я уже говорил, что TDD – это непросто, но что действительно сложно, так это пытаться применять TDD для кода, который изначально не был спроектирован для применения этого подхода! Почему? Эту тему Scrum и XP: заметки с передовой 62 можно долго обсуждать, но я, пожалуй, остановлюсь. Приберегу мысли для следующей книги: "TDD: Заметки с передовой" :o) В своё время мы потратили много времени в попытках автоматизировать интеграционное тестирование одной из сложных систем, код которой мы унаследовали в ужасном состоянии и без единого теста. При выходе каждого релиза мы выделяли команду тестировщиков, которые выполняли весь набор сложных регрессионных тестов и тестов производительности. Регрессионное тестирование выполнялось преимущественно вручную, что существенно замедляло процессы разработки и выпуска релизов. Тогда нашей целью стало автоматизировать все эти тесты. Однако, побившись пару месяцев головой об стену, мы поняли, что не приблизились к цели ни на йоту. Тогда мы изменили подход. Мы признали тот факт, что автоматизировать регрессионное тестирование нам не по силам, и задали себе вопрос: "Как можно уменьшить время тестирования?". Это была игровая система, и мы выяснили, что большую часть времени тестирующая команда тратит на тривиальные задачи, такие как настройку тестового турнира или ожидание начала турнира. Поэтому мы создали утилиты для выполнения этих операций. Маленькие, доступные нажатием горячих клавиш скрипты, которые выполняли всю подготовительную работу, позволяя тестировщикам сосредоточиться непосредственно на тестировании. А вот эти усилия уже окупились сполна! По уму мы должны были поступить так с самого начала. Но мы были настолько зациклены на автоматизации, что забыли про эволюционный подход, в котором первым шагом было бы создание окружения, позволяющего сделать ручное тестирование более эффективным. |