среда, 14 сентября 2011 г.

Why test first?

TDD != XP; TDD in XP;

Опять возвращаемся к холиварам. Здесь не будет обсуждаться ценность написания тестов (для любого программиста, который разрабатывал системы больше года и поддерживал legacy code это ясно как божий день). А поговорим вот о чем. Зачем писать тесты до кода, если можно написать после и разницы вроде как бы и нет? TDD вообще очень сильно обросло мифами. Существуют руководители компаний, которые считают TDD мифом, а живых TDD-шников принимают за снежного человека. Есть, однако прогрессивные менеджеры, которые считают что писать в стиле TDD возможно, но надо стукнуться головой об стенку. Но разговор опять будет не об этом, а о плюсах и минусах использования TDD.


Преимущества:

  1. Потом равносильно никогда (многие комманды срывались, когда тесты надо было писать после кода, так как фичи и change request'ы имеют свойства никогда не кончаться). Плюс под давлением повышается риск пробуждения свиньи в себе и программисты опять перестают писать тесты.  Итого, замкнутый круг - из-за стресса мы пишем меньше тестов, что приводит к росту ошибок, рост ошибок приводит к росту стресса. Еще плачевнее результат, когда написание юнит тестов доверяют другому отделу или отдельному программисту (ребята, мне вас жаль). Мало кто пишет код и думает о том, а как собственно говоря, тестировать все это хозяйство. Опять получаем замкнутый круг - чтобы написать тесты нужен рефакторинг, а чтобы сделать рефакторинг нужны тесты.
  2. It's more funny to code with test first. TDD позволяет привнести игровой элемент в работу программиста (ага, вот он неработающий тест, сейчас мы заставим его пройти). Ни для кого не секрет, что программисты это не рабочие у станка и мы не можем выдавать 150 деталей в час (фичи/в день). Вдобавок, эта методология позволяет избавиться от прокрастинации, так как TDD позволяет двигаться маленькими шажками (пресловутый red-green-refactor) и сдвинуться с мертвой точки.
  3. Testability Design по определению. Как говаривал Кент Бек, если трудно тестировать, значит  есть архитектурные проблемы. Test first заставит вас разделять зависимости, разгружать классы, убивать синглтоны и т.д. и т.п.   
  4. You are the first client of own code. Можете сразу ощутить, насколько удобно пользоваться собственным же творением)). Помогает избавиться от невразумительных API.
  5. Выпиливание непокрытых ветвей кода. Ведь если каждая новая ветка кода пишется после теста, то так называемый branch coverage = 100%. (По статистике самое большое число ошибок приходится на if операторы).
  6. Нечасто, но бывает, что test first позволяет обнаружить, что тест написан с ошибкой. Пример: приходит change request, пишем сначала тест, запускаем - получаем зеленую полоску( а должны были красную) => в тесте что - то не так( либо кто-то уже сделал данную функциональность без тестов, ай я яй :-) ).
  7. Позволяет большинству программистов еще раз переосмыслить ООП и понять, что ООП это не только совокупность определений, как говаривал наш преподаватель.
  8. Пишется минимальное количество кода, что уберегает разработчиков от overdesign. Что происходит с кодом, который пишется впрок, но не используется в проекте? Он никогда не удаляется.  Код на будущее, написанный даже не потому, что по ТЗ он понадобится, а потому, что может пригодится на случай атомный войны убивает проект, производит расфокусировку, замутняет контекст, мешая разобраться, а что собственно говоря здесь важно, а что нет, увеличивая нагрузку на мозг программиста. Главный императив программирования - борьба со сложностью. (cм. Макконнелла). TDD - это достаточно простой способ получить "чистый код, который работает".
  9. Если уж вы и собираетесь писать тесты (а вы же собираетесь? :-) )для вашего кода, то вы ничего не потеряете, поменяв местами написание тестов и написание кода.  
Недостатки :


  1. Высокий порог вхождения. Ну очень высокий - замедление работы колоссальное на первых порах (в 2 - 3 раза). 
  2. Необходимость стукнуться головой об стену))
  3. Из-за пункта 1 малое число практикующих TDD.
  4. В некоторый средах цикл red-green-refactor увеличивается из-за невразумительной IDE (привет, XCode!). 
  5. Неприменимость в процедурно-ориентированных языкак, низкоуровневом системном программированим (опыт имею нулевой минимальный, true юникс хакеры отзовитесь, поделитесь опытом в комментах, как вы тестируете свой код?).
  6. Может сложиться ощущение, что TDD это серебряная пуля.
Что почитать и посмотреть по теме:
  1. TDD By Example Кента Бека. 300 страниц легкочитаемого с юмором написанного текста про TDD, TDD и дизайн, паттерны и приемы TDD.
  2. Первой книги должно хватить, но ненасытные могут насладиться "Рефакторингом с использованием шаблонов" от Джошуа Кириевски. http://www.ozon.ru/context/detail/id/2909721/. Это, наверное, первая книга которая подняла такую проблему как overdesign и гибельность оного для проектов.
  3. Крайне классная презентация Ten Ways to improve your code http://www.infoq.com/presentations/10-Ways-to-Better-Code-Neal-Ford. Именно в ней появился тезис first client of your code.