20 сент. 2009 г.

Test-Driven Development (TDD) Workshop - как пощупать инженерную практику, чтобы не было больно на утро

Сегодня об инженерных практиках, которые активно используются в гибких (agile) методологиях (хотя эти практики свободно масштабируются на произвольные процессы) ходит много споров и обсуждений. В том числе и о TDD из процесса XP. 

При этом возникает ряд проблем внедрения этих практик. Их рассмотрение я оставлю out of scope. Но желание разработчиков пощупать, потестировать подход остается и даже возрастает (с каждой прочитанной книгой ;-). 

В свое время я разработал игру-симуляцию, которая позволила бы это сделать с базовым набором XP-практик: TDD, pair programming, iterative development и simple design. И после проведения серии этих воркшопов назрел целый ряд интересных выводов:

  1. Игровая форма рулит.  Мы все читали и слышали, что игры - один из самых эффективных инструментов обучения. Но на практике это превосходит ожидания. 2 часа кодирования пролетают, по словам участников, как 30 минут. Даже для не-разработчиков (тестеров, pm-ов).
  2. Воркшоп дает крайне эффективную обратную связь. Наблюдение за работающими над заданием участниками - ценнейший источник информации о них. А результаты выполнения задания говорят сами за себя.
  3. Участники сами приходят к выводу о целесообразности используемой практики. Правильно выстроенный воркшоп заменяет килограмм лекций о необходимости, например, модульного тестирования.
  4. Воркшоп снимает страх или лень использования практик. В игровой форме (когда нет контроля начальства сверху) участник может попробовать использовать практики, которые в проекте избегает из-за инерции или риска нарушения процесса.

Статистика проведения эвента показывает его высокую образовательную эффективность. Поэтому, собственно, message: Коллеги pm-ы, проектировщики и разработчики! Если Вы хотите внедрить в своем коллективе какую-либо инженерную практику практически без сопротивления, создайте собственную игру-симуляцию, учитывающую специфику коллектива. Эта игра создаст максимально комфортные условия знакомства с практикой и при правильной проработке этой игры подтолкнет коллег использовать практику.

Безусловно, возникнет ряд сугубо методических нюансов - как выстроить игру, максимально раскрывающую все грани практики. У меня, даже с учетом богатого опыта проведения обучения, получилось отточить все детали только после 3-4 проведений. Зато теперь этот воркшоп - крайне эффективный инструмент знакомства с практиками, выработки навыков и передачи знаний; игра стоила свеч ))

Если кто-то захочет использовать такой подход, но имеет методические трудности - пишите, буду рад помочь. Хотя, крайне часто хорошие специалисты так же нагружаются образовательной активностью для junior-коллег, так что создание такого обучающего проекта их не введет в ступор ))) Надеюсь, мой message об эффективности таких подходов будет услышан )

Успехов!

10 комментариев:

ekr комментирует...

Самое, наверное, ценное - обсуждение и понимание результатов. Выложил каркас практики с обсуждением на slideshare.

ekr комментирует...

По просьбам в личку выложил теоретический блок по тестированию и TDD patterns на slideshare.

batigoal комментирует...

Так и не нашел, как здесь написать в личку, поэтому пишу в комментарии.

Мы собираемся провести небольшой внутрикомандный тренинг по TDD (на основании небольшого проекта, в котором мы его частично применяли). Прошу разрешения использовать на нем материалы Вашей презентации.

ekr комментирует...

В личку - это на почту. Ящичек указан справа сверху ))
К тому же, всегда можно через винград со мной связаться.

Разрешение даю. Конечно же, используйте.

Краткий roadmap тренинга:
1. Теоретический блок. Материала в презентации очень много, поэтому заранее выбирается только необходимые куски. У меня обычно ограничение по времени - 3 часа на всё, поэтому на теорию отбирал материала на час, контент - в зависимости от аудитории.
Обязательно надо рассказать про: основы unit-тетирования (тесткейс, фикстура, assertion) на примере j(n)unit, simple design (vs up-front design) и ключевые tdd patterns (5-7 шт.). Остальное - по необходимости и достатку времени.
В принципе, я везде пишу предварительные требования, но практика оказывает, что на них забивают и идут все. К этому надо быть готовым.
2. Практика-игра (обычно 2 часа, можно больше, но никак не меньше). Здесь мы эмулируем разработку приложения, заказчиком выступает инструктор.
Инструктор дает функц. требования в виде диаграммы юзкейсов. Слушатели ведут разработку в парах, один - ведущий разработчик, второй - ревьюер. Инструктор должен раз в 15 минут сигнализировать "меняемся активностью в парах" и следить, чтобы они управление (клаву и мышу) передавали друг другу.
2.1 Первая итерация (час).
Вся практика обсуждается по презентации TDD Workshop Discussions последовательно, не надо забегать вперед - там сюрпризы.
Даются требования для первой итерации. Проходит час (4 смены активности внутри пар) и после этого обсуждаются типичные ошибки и вопросы для первой итерации. При этом инструктор все время призывает писать понятный самодокументирующийся код.
2.2. Вторая итерация.
Требования к системе меняются (добавляются). И самое главное - инструктор меняет пары местами, чтобы они продолжили на чужой машине с чужим кодом. Задача - заставить их понять, что код надо писать самодокументирующийся.
После четырех 15-минуток разработка завершается и обсуждаются типичные ошибки и вопросы по второй итерации по презентации Discussions.

Вот такой примерный roadmap. По ходу подготовки возникнут вопросы. Сигнальте - буду рад ответить.

И есть еще два варианта - если у Вас средняя команда и больше и Вы в Москве, то:
1. Можно устроить этот воркшоп у нас в офисе под Вашу команду. Мы постоянно проводим семинары, вся инфраструктура есть.
2. Наши инструкторы (скорее всего, я) могут провести семинар на Вашей площадке.

Будут еще вопросы - буду рад ответить.

ekr комментирует...

И еще важная ремарочка: если времени будет больше, то следует увеличивать количество итераций, но не их длительность!
Это связано с тем, что постоянно должно быть давление по времени - это провоцирует их на использование simple design. Они постоянно должны не успевать.

batigoal комментирует...

Большое спасибо за помощь! Применим.

Почтовый адрес не заметил, виноват. Глаз автоматически отфильтровывает картинки :)

Территориально мы находимся в Питере (Alcatel-Lucent). В данном случае тренинг практически наверняка будет проводиться своими силами, потому что мы хотим поделитьс именно СВОИМ опытом разработки, т.к. другим членам нашей команды, весьма вероятно, придется взаимодейстовать с теми же продуктами, и наш контекст одинаков.

Большинство разработчиков уже имеет минимальный опыт или хотя бы теоретическое понимание практики unit-тестирования и TDD, поэтому за это условие я спокоен.

Вдобавок к программе, предусмотренной вашим материалом, хотим еще включить блок по Mockito - нам он показался исключительно удобным и полезным инструментом.

batigoal комментирует...

Есть еще такой вопрос. Как Вы относитесь к такому явлению, как влияние тестовго кода на продуктивный код?

Два примера из практики:

1) При работе метода генерится уникальное имя файла. Чтобы упростить тесты, элементарный метод-генератор (return prefix+timestamp) выносится в отдельный класс-стратегию. Без тестов он был бы просто заинлайнен - налицо упрощение.
2) для удобства тестирования некоторые методы сменили область видимости с приватных на package-visible. Тоже, на мой взгляд, некошерно.

ekr комментирует...

Отлично ))
Если будете давать что-то новое для них (мокито), не забудьте время увеличить. Или на дом дать разобраться.

Успехов! ))

ekr комментирует...

По влиянию тестового кода на продуктивный:
Начну издалека ))
Есть такое нефункциональное требование к системам, помимо надежности, масштабируемости и др. - тестируемость. При явном определении этого требования в списке нефункц. треб-ий разработчики и проектировщики будут применять решения, отличные от тех, какие они бы применяли без введения этого требования.
По сути TDD в том числе - введение разработчиками требования тестируемости для самих же себя (хотя оно не присутствует явно в списке атрибутов качества системы).
Поэтому ответ на Ваш вопрос простой - надо понять, каков приоритет требования теструемости (было оно в списке требований или разработчик сам его для себя ввел). Если четко описать все требования и критерии их валидации, то получится стройная система, которая позволит решать конфликты между ними.

В приведенных случаях конфликт возникает между требованиями тестируемости и поддерживаемости (supportability) - "код становится сложнее", "не кошерно". Решите для себя, что важнее и в каких случаях - и зафиксируйте в виде рекомендации (guideline) для команды.

Мое скромное мнение (не претендующее на истину в последней инстанции) - testability важнее. Это доказывается моей практикой и опытом. Но у всех свои условия - надо каждый раз думать, как поступать.

PS Этот пример еще раз подтверждает, как важно разработчикам и проектировщикам знать смежные области - анализ требований, например.

batigoal комментирует...

Исчерпывающее объяснение. Спасибо!