Вот вы думаете зря что ли в TDD и GTD две буквы из трех одинаковые? Вы еще, наверное, думаете, что TDD - это когда тесты пишут перед реализацией.
Дело в том, что нужно быстро взять и прочитать TDD by Example Кента Бека и все сразу станет на место - не может ведь быть, что 240 страниц текста посвящено только test first принципу.
Не может быть и не есть.
Кент, например, рассказывает нам, что основной принцип TDD - это движение маленькими шажками. При решении какой-то задачи, он предлагает записать её на листик (ну, в VS есть настоящий to do list, такой же как и в Outlook) и прикинуть, понятно ли как решить задачу прямо сейчас. Если нет, то подумать, какой шаг может нас приблизить к решению основной проблемы. Таким образом он предлагает идти рекурсивно до первой простейшей атомарной задачи, которую мы и возьмем для реализации.
Далее предлагается написать тест для этой задачи и прогнать его, чтобы убедиться, что он падает. Помимо чисто психологического аспекта, как показывает практика (вы будете смеяться), есть и практическая польза - иногда тест не падает.
Справившись наконец с такой простейшей задачей как падающий тест, следующим шагом нам требуется написать реализацию максимально простым способом. То есть сделать тест зеленым как можно быстрее - это раз, и делая только то, что необходимо для теста - это два.
Более того, если во время реализации пришла какая-то супер-идея как сделать что-то лучше, то мы не отвлекаемся, а просто вносим её в наш to do list. Это важно, мы выгружаем её из мозга, чтобы она не мешалась у нас под ногами и не мешала нам сконцентрироваться над текущей задачей.
После реализации теста, мы можем поставить зеленую галочку в нашем to do list, что, как мы уже знаем, несет в себе позитивный мотивирующий заряд и дает нам ощущение здорового прогресса.
Причем, стоит особо отметить, - не будь у нас зеленого теста (или теста вообще), мы бы не были на 100% уверены в завершенности задачи. А точнее мы бы на 99% процентов были уверены, что первый запуск выдаст нам парочку-другую - а может и больше - непростых ошибок.
И ведь часто мы знаем, где может крыться проблема, потому что не уверены, как работает какой-то метод фреймворка, который мы впервые используем. Эта неуверенность нас бы постоянно отвлекала, снижая концентрацию и производительность, не напиши мы сразу тест.
Более того, следующим шагом является небольшая порция рефакторинга, то есть мы причесываем наш код и делаем его чистым и красивым, - несомненный мотивирующий фактор для здорового программиста.
Мы не боимся что-то поломать, потому что если возникает проблема, то тесты, которые мы написали ранее, сразу дадут нам знать об этом. Мы не забываем, что 80% времени программист читает код, а не пишет, поэтому постоянный рефакторинг - это эффективный способ увеличить производительность нашу и наших коллег.
Итак, после разумной порции рефакторинга, мы можем браться за следующую задачу - мы пересматриваем наш to do list, а вдруг какие-то из ранее записанных задач уже понятно как решать буквально с первого взгляда. Если да, то беремся и решаем. Если нет, то мы продолжаем разбивать проблему на маленькие кусочки, выходя на элементарные задачи, которые мы можем решить сходу. И так до тех пор, пока ранее записанная проблема сама не станет одной из таких элементарных задач.
В результате, мы все время движемся маленькими шагами и при каждом очередном зеленом тесте получаем тот необходимый нам импульс "Фуух, сделал!", мотивирующий нас на движение вперед, и, в то же время, не забываем удовлетворять наше чувство прекрасного, уделяя время на правильную структуризацию кода (рефакторинг). Мы делаем только то, что необходимо для прогресса, максимально простым и быстрым способом. Мы уверены в будущем и не боимся, что слишком простая реализация может не удовлетворять всем нашим потребностям в будущем - код легко читать и менять, а тесты застрахуют нас от ошибок.
Господа, это и есть принципы Getting Things Done, адаптированные к программированию, то есть TDD - это и есть, не побоюсь громких слов, эффективная система time management для разработчиков.
И помните, только настоящим пацанам не нужны тесты!
Вот такой получился опус в продолжение темы о TDD.
ОтветитьУдалитьhttp://www.grodnosoft.by/2010/09/test-driven-development-tak-daleko-tak.html
Я считаю, что самый хороший способ научиться TDD - это парное программирование :) Учиться самому однозначно непросто, но можно (я тому живой и еще ходячий пример).
ОтветитьУдалитьДругой вопрос - внедрение. Если учиться сложно, то внедрить еще тяжелее. Нужно много пороха в пороховницах, но зато потом коллеги даже благодраны.
Статистика говорит нам, что тесты добавляют +30% к разработке, но с сильной экономией на баг фиксинге и рефакторинге на более поздних этапах. Но это когда уже все умеют....
Согласен насчет парного программирования, но мне кажется, что в этом случае хотя бы один человек из пары должен ориентироваться в TDD.
ОтветитьУдалитьВ любом случае меня больше интересует (и заботит) внедрение этой практики. Тут, как вы правильно заметили, все еще тяжелее. Думаю имеет смысл:
1) продвигать TDD своим примером
2) попробовать посчитать выгоду от применения на небольшой задаче и представить результат руководству
Тут, конечно же, встает вопрос об ответственности за результат - но я в своем случае справлюсь :)
Да, стоит согласовать это с руководством.
ОтветитьУдалитьТут еще один момент стоит учитывать. Есть понятие testable и not-testable код.
Так вот если сначала написали кучу кода и потом подумали - дай-ка мы юнит-тестами его покроем, то выяснится, что код не testable (так как код писался без расчета на юнит-тесты), писать тесты тяжело и шансов на успех значительно меньше.
Если писать тесты сразу, то код автоматически пишется так, чтобы было удобно тестировать. И этого не надо боятся, потому что на самом деле это скорее означает, что мы достигаем loose coupling, то есть зависимостей в коде меньше, потому и тестировать легче.
Да, покрытие существующего кода юнит-тестами, как правило, дело гиблое. Приходилось с этим сталкиваться. В принципе это может быть дополнительным доводом в разговоре с руководством. Мол, "вы же хотели покрыть все юнит-тестами, но ничего не получилось. Есть решение!" - в таком духе.
ОтветитьУдалить