Какова отрицательная сторона вашего опыта TDD? Считаете ли вы, что детские шаги (самое простое решение, чтобы сделать тест зеленым) раздражают и бесполезны? Считаете ли вы, что тесты без значения (когда тест изначально имеет смысл, но в финальной реализации проверяет ту же логику, что и другие тесты), критически важны для обслуживания? и т.п.
Приведенные выше вопросы касаются вещей, которые мне неудобны во время моего опыта TDD. Поэтому мне интересно, испытывают ли другие разработчики аналогичные чувства и что они о них думают.
Был бы благодарен за ссылки на статьи, описывающие отрицательные стороны TDD (Google полон положительных и часто фанатичных статей).
Ответы:
Как и все, что попадает под баннер «Agile», TDD в теории звучит хорошо, но на практике не очень понятно, насколько он хорош (а также, как и большинство «Agile» вещей, вам говорят, что если вы не нравится, ты делаешь это неправильно).
Определение TDD не выгравировано в камне: такие ребята, как Кент Бек, требуют, чтобы некомпилируемый тест был написан до одной строки кода, а каждая отдельная строка кода должна быть написана, чтобы пройти неудачный тест. Передний дизайн минимален и все движетсяпо тестам. Это просто не работает. Я видел крупное корпоративное приложение, разработанное с использованием этой методологии, и я надеюсь, что это худший код, который я вижу за свою карьеру (он не за горами; и это несмотря на то, что над ним работают талантливые разработчики). Из того, что я видел, это приводит к огромному количеству плохо продуманных тестов, которые в основном проверяют, что происходят вызовы функций, что исключения генерируются, когда переменные равны нулю, и фальшивый фреймворк получает полную тренировку (whoop-de-whoop); ваш производственный код тесно связан с этими тестами, и мечта о постоянном и простом рефакторинге не появляется - на самом деле люди даже реже могут исправить плохой код из-за всех тестов, которые он сломает.
Наоборот, я слышал, что люди утверждают, что TDD означает проектирование тестов заранее на высоком уровне как часть фазы планирования - наряду с архитектурным дизайном. Эти тесты могут изменяться во время разработки, когда появляется больше информации, но они были тщательно рассмотрены и предлагают хорошее руководство относительно того, что код должен делать на самом деле. Для меня это имеет смысл.
источник
Это ( Clojure автор) Рич Хикки интервью содержит следующее. Я чувствую себя на 100% сочувствующим:
Еще одно подобное заявление Дональда Кнута из интервью книги Coders at Work , скопированное отсюда :
источник
Мой негативный опыт с TDD был моим первым. TDD звучало для меня замечательно, я проводил тестирование годами и все еще думал о ужасах. Я хотел раздавить каждую ошибку, прежде чем она превратилась в сборку. К сожалению, использование TDD не гарантирует, что вы будете писать хорошие тесты. Фактически, моя первоначальная предрасположенность заключалась в написании простых тестов, которые генерировали простой код. Действительно простой код, содержащий мало абстракций. Действительно простые тесты, которые были переплетены с внутренними классами. И как только у вас будет несколько тысяч маленьких тестов, вы не почувствуете, что движетесь быстрее, если вам нужно изменить сотню из них, чтобы реорганизовать ваш код, чтобы использовать очень важную концепцию домена X.
У меня загорелся свет - TDD не является навыком тестирования. Это дизайнерский навык. Он может только привести вас к хорошему, простому, работоспособному коду с практикой и постоянным знанием направлений проектирования, в которых он вас ведет. Если вы пишете тесты ради покрытия кода, вы собираетесь создавать хрупкие тесты. Если вы пишете тесты, помогающие создавать абстракции, то это просто более строгий способ написания нисходящего кода. Сначала вы видите код с точки зрения вызывающего, что побуждает вас сделать его жизнь проще, а не отражать внутреннюю часть класса на его внешнем краю.
Я думаю, что TDD полезен, но я не догматичен в этом. Если эти «бесполезные испытания» затрудняют техническое обслуживание - удалите их! Я отношусь к тестам так же, как и к остальному коду. Если это можно изменить и упростить, сделайте это!
Я не видел это лично, но я слышал, что в некоторых местах отслеживаются покрытие кода и количество тестов. Так что, если сбор метрик является побочным эффектом TDD, то я также могу рассматривать это как негатив. Я с энтузиазмом удаляю 1000 строк кода, и если это устареет 20 тестов и отбросит мой охват кода%, ну хорошо.
источник
Я собираюсь выйти на конечности здесь и заявить с жестокой честностью, что это буквально ритуальная трата времени. (В большинстве ситуаций.)
Я купил книгу по модульному тестированию, в которой также обсуждался TDD, и, хотя я согласен с преимуществами UT, после примерно ста часов работы с TDD я отказался от нее по множеству причин. Я вроде кросс-постинг здесь, но TDD:
Другое беспокойство - обсуждаемая степень совершенства, до которой нужно сделать TDD, чтобы сделать это успешно. Некоторые настаивают на том, что если TDD не будет постоянно выполняться всеми членами команды с самого начала проекта, вы будете только страдать. Другие настаивают на том, что никто не делает TDD по книге. Если они оба верны, то из этого следует, что практикующие TDD страдают, осознают они это или нет.
Конечно, если утверждают, что, делая вещи в стиле TDD, вы придете к проектам, которые могут легко работать с TDD, что ж, есть гораздо более быстрые способы достичь этого, а именно путем изучения концепций компонуемости. Там много ресурсов, даже много строгой математической теории (в основном в функциональном программировании, но также и в других областях). Почему бы не тратить все свое время на обучение TDD ?
В культурном отношении TDD демонстрирует признаки ритуальной практики. Это едет на вине; это побуждает процедуру к пониманию; у него тонны доктрин и лозунгов («притворяйся, пока не сделаешь» действительно вызывает тревогу, если смотреть на это объективно). Определение слова "ритуал" в Википедии на самом деле весьма уместно:
источник
Чтобы добавить, еще одна проблема с TDD, которую я заметил:
TDD вызывает непреднамеренное смещение акцента команды разработчиков с кода качества на тестовые случаи и покрытие кода! Мне лично не понравился TDD, так как он делает меня менее креативным и делает разработку программного обеспечения скучным механическим процессом ! Модульные тестовые сценарии полезны при разумном использовании, но становятся бременем, когда рассматриваются цели разработки программного обеспечения.
Я знаю парня, который является менеджером и технически скучным, когда одержим TDD. Для него это было настолько волшебным, что он верил, что это принесет волшебные решения всех проблем его плохо спроектированного программного обеспечения с наименьшим количеством поддерживаемого кода. Не сказать, что случилось с этим проектом - он с треском провалился в его руках, в то время как все его тестовые шкафы были зелеными. Я предполагаю, что TDD помог ему получить некоторую статистическую информацию, такую как «99/100 моих дел зеленые» и т. Д., И это стало причиной его одержимости, поскольку он никогда не сможет оценить качество или предложить улучшения в дизайне.
источник
Мой основной негативный опыт - попытка использовать TDD для редактирования кода другого программиста, у которого нет ни тестов, ни очень базовых интеграционных тестов. Когда я иду, чтобы добавить функцию или исправить проблему с указанным кодом; Я предпочел бы сначала написать тест (способ TDD). К сожалению, код тесно связан, и я не могу ничего протестировать без большого количества рефакторинга.
В любом случае рефакторинг - отличное упражнение, но он необходим для приведения кода в тестируемое состояние. И после этого шага у меня нет сдержек и противовесов, чтобы посмотреть, не сломались ли мои изменения; кроме запуска приложения и изучения каждого варианта использования.
С другой стороны, добавление функций / исправление ошибок в проект TDD становится очень простым. По своей природе код, написанный с использованием TDD, обычно довольно не связан с небольшими кусочками для работы.
В любом случае, TDD является ориентиром. Следуйте по нему до точки, где вы обнаружите, что вы получите максимальную эффективность. Достойный тестовый охват и разделенный код, хорошо написанный код.
источник
У меня сложилось впечатление, что я иногда слишком полагаюсь на свои тесты, когда речь идет о разработке системы. Я в основном слишком низок в деталях реализации, чтобы сделать шаг назад, чтобы взглянуть на более широкую картину. Это часто приводит к излишне сложному дизайну. Я знаю, я должен реорганизовать код, но иногда у меня складывается впечатление, что я мог бы сэкономить много времени, делая шаг назад чаще.
При этом, если у вас есть фреймворк, такой как рельсы, где ваши архитектурные решения очень ограничены, этих проблем в принципе не существует
Еще одна проблема - когда вы слепо доверяете своим тестам. Правда - как и любой другой код - ваши тесты тоже могут иметь ошибки. Поэтому будьте так же критичны к своим тестам, как и к своей реализации.
источник
Как большой поклонник TDD я иногда вижу эти недостатки
Затраты на сопровождение тестового кода для похожих тестов, которые отличаются незначительно (создается с помощью дублирования кода (он же копирование-вставка-наследование)). Если у вас уже есть такой, его легко создать. Но если вы не проведете рефакторинг тестового кода, устраняя дублирование кода во вспомогательные методы, вам может потребоваться некоторое время для исправления тестов, если детали реализации вашего бизнес-кода изменятся.
Если вы испытываете нехватку времени, у вас может возникнуть желание устранить неработающие тесты (или закомментировать их) вместо того, чтобы их исправлять . Таким образом, вы теряете инвестиции в тесты
источник
Мне еще не приходилось сталкиваться с несколькими сценариями в качестве разработчика игр, в которых TDD стоил того. И случай, в котором это было, был частью кода, который был чисто математическим по своей природе и нуждался в серьезном подходе для одновременной проверки огромного числа крайних случаев - редкая необходимость.
Может быть что - то, когда - нибудь передумаю, но среди XP практик, идея рефакторинга нещадно , и код эволюционирует свою собственную форму, гораздо более важной и привести к наибольшей производительности для меня, ср цитата из статьи Джеймса Ньюкирка :
Концепции мужества и ужесточения петель обратной связи, которые он упоминает, также, на мой взгляд, являются ключом к производительности.
источник
Мой отрицательный опыт TDD, каким бы ограниченным он ни был, просто зная, с чего начать! Например, я попытаюсь сделать что-то TDD и либо не знаю, с чего начать запрещать тестирование тривиальных вещей (могу ли я создать новый
Foo
объект, могу ли я передать aQuux
вBaz
и т. Д. Тесты, которые ничего не тестируют ) или, если я пытаюсь реализовать его в существующем проекте, я обнаружу, что мне придется переписать различные классы, чтобы иметь возможность использовать их в TDD. Конечным результатом является то, что я быстро полностью отказываюсь от этого понятия.Вероятно, это не помогает, что часто я единственный человек во всей компании, который знает, что такое модульное тестирование (TDD или другое) и почему это хорошо.
источник
Foo
с объектами Mock, а не напрямую, затем вы можете вызвать функцию, которую вы хотите протестировать, а затем проверить, что mock-функции вызывались с ожидаемыми вами функциями. Поддельные объекты - это активная технология, которая помогает разъединить модули и сделать их тестируемыми. Вот почему синглтоны злые, потому что вы часто не можете просто издеваться над ними. * 8 ')Quux
Baz
Фанаты TDD.
Для меня они - лишь одна из длинной череды религиозных психов, стучащихся в мою дверь, пытающихся доказать, что мой способ ведения дел непоправимо нарушен, и единственный путь к спасению - это Иисус, Кент Бэк или Юнит-тестирование.
IMO, их самая большая ложь в том, что TDD приведет вас к
спасениюлучшего дизайна алгоритма. Смотрите знаменитый Солдуку Солвер, написанный в TDD: здесь , здесь , здесь , здесь и здесьИ сравните его. Решатель Peter Norvig sudoku сделан не с использованием TDD, а с использованием старомодной техники: http://norvig.com/sudoku.html
источник
Если вы используете TDD из этих «фанатичных» статей, у вас будет неправильное ощущение безопасности, что ваше программное обеспечение не содержит ошибок.
источник
У TDD есть некоторые преимущества:
TDD о долгосрочных инвестициях. Усилия окупаются, когда вы переходите в режим обслуживания вашего приложения, и если приложение не планируется достичь этого уровня, вы никогда не сможете вернуть инвестиции.
Я считаю, что TDD красно-зеленый цикл с детскими шагами похож на контрольный список для самолета. Досадно и утомительно проверять каждую вещь в самолете перед взлетом, особенно если это тривиально просто (шаги ребенка TDD), но было обнаружено, что это повышает безопасность. Помимо проверки, что все работает, это, по сути, сбрасывает самолет . Другими словами, самолет перезагружается перед каждым взлетом.
источник
Мой негативный опыт с TDD - это то, что я чувствую со многими новыми и раскрученными вещами. На самом деле мне нравится TDD, потому что он обеспечивает достоверность моего кода, и что еще более важно: я могу распознать провальные тесты после добавления нового кода или любого вида рефакторинга.
Что меня раздражает в TDD, так это то, что в нем много правил или рекомендаций. Поскольку это все еще довольно новое, мы, как большинство из нас, начинаем в TDD. Так что то, что хорошо для некоторых из нас, может не работать для других. Что я хочу сказать, так это то, что не существует настоящего «неправильного или правильного» способа выполнения TDD: есть способ, который работает для меня - и моей команды, если она у меня есть.
Поэтому до тех пор, пока вы пишете тесты - до или после рабочего кода на самом деле не имеет значения ИМХО - я не уверен, что тестирование действительно означает, что вы должны следовать всем рекомендациям, которые изложены прямо сейчас, поскольку они еще не доказали, что они идеальное решение для каждодневной работы. Если вы найдете лучший способ написания тестов, вы должны опубликовать его в блоге, обсудить его здесь или написать статью об этом. Таким образом, примерно через десять лет мы могли бы поделиться достаточным опытом, чтобы определить, какое правило TDD можно считать хорошим или нет в определенной ситуации.
источник
Я не раз писал код, от которого отказались на следующий день, так как он был неуклюжим. Я перезапустил с TDD, и решение было лучше. Таким образом, у меня не было слишком много в линии отрицательного опыта TDD. Однако, как говорится, я потратил время на обдумывание проблемы и нахождение лучшего решения за пределами пространства TDD.
источник
Я обнаружил, что TDD работает плохо, когда речь идет о новых системах. Я разработчик видеоигр, и недавно использовал TDD для создания системы, которая использует несколько простых способов поведения для создания реалистичного движения объекта.
Например, есть поведения, ответственные за то, что вы уводили вас из опасных зон разных типов, и те, которые ответственны за то, что вы перемещали вас к интересным областям разных типов. Объединение результатов каждого поведения создает заключительное движение.
Внутренности системы были легко реализованы, и TDD был полезен для определения того, за что должна отвечать каждая подсистема.
Однако я столкнулся с проблемами, когда речь зашла о том, как поведенческие взаимодействия взаимодействуют, и что более важно, как они взаимодействуют с течением времени. Часто не было правильного ответа, и хотя мои первоначальные тесты проходили, QA могла продолжать находить крайние случаи, когда система не работала. Чтобы найти правильное решение, мне пришлось повторить несколько различных вариантов поведения, и если я обновлял тесты каждый раз, чтобы отразить новые варианты поведения, прежде чем проверять их работу в игре, я мог бы снова и снова выбрасывать тесты снова и снова. Поэтому я удалил эти тесты.
Возможно, мне следовало бы провести более сильные тесты, в которых были бы обнаружены крайние случаи, обнаруженные QA, но когда у вас есть такая система, которая работает на вершине многих систем физики и геймплея, и вы со временем сталкиваетесь с поведением, это становится чем-то вроде кошмар, чтобы точно указать, что происходит.
Я почти наверняка допустил ошибки в своем подходе, и, как я уже сказал, для внутренней системы TDD работал блестяще и даже поддерживал несколько оптимизирующих рефакторингов.
источник