TDD - Как начать действительно думать TDD? [закрытый]

Я читал о Гибком, методологиях XP и TDDs.

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

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

У меня есть немного классов, где у меня есть чистая протестированная единица, кодируют, но я, может казаться, не продолжаю процесс, когда насмешки входят в изображение. Кроме того, я время от времени вижу: "не это слишком тривиальный для записи теста для него" синдром.

Как делают Вас, парни думают, что я должен обработать это?

73
задан MPelletier 21 October 2010 в 14:53
поделиться

16 ответов

Мне интересно, что ни один из ответов до сих пор не касался того, что я считаю фундаментальным пониманием современных практик разработки, а именно того, что «старомодный» способ написания программного обеспечения путем сбора требований, проведения анализа и моделирование желаемой системы перед написанием любого кода на самом деле имело для этого немало.

TDD фактически воплощает это в некоторой степени .

Чтобы написать тест, вы сначала должны знать - выражаясь очень простыми словами - каковы будут ваши входные данные и каковы будут ваши ожидаемые результаты.

Получив эти знания, вы можете написать тест для проверки некоторого фрагмента мифического кода, а также, в определенной степени, того, с какими другими артефактами этот код будет взаимодействовать, прежде чем вы напишете сам этот код или создадите эти артефакты.

Это то, что мы раньше называли «инженерией требований» и «системным анализом» в старых методах «водопада».

Более того, вы обнаружите, что как только вы поймете требования на этом уровне, написание тестов станет естественным (в конце концов, это просто выражение в коде описания функциональности, воплощенного в этих требованиях).

И при написании кода, который выражает требования в форме тестов, вы выявите пробелы и недоразумения в требованиях, прежде чем вы внесете эти пробелы и недоразумения в проект в виде исполняемого кода.

Для современных практиков «гибких» методов признать, что они участвуют в серии «водопадов», я думаю, слишком неловко, поэтому потребность в разработке и понимании требований скрывается за языком, который говорит о необходимости обращайтесь к этим вещам, отчаянно пытаясь избежать признания того, что «Аджайл» (как обычно понимается или, возможно, неправильно понимается) выбросил ребенка с большим количеством воды в ванне.

48
ответ дан 3 July 2019 в 13:07
поделиться

"Итак, хотя человек действительно верит в TDD, вы на самом деле в конечном итоге возвращаетесь к старому стилю из-за давления времени / из-за нехватки времени / сроков выполнения проекта."

На самом деле, я не думаю, что это может быть правдой.

Если вы "возвращаетесь к старому стилю", то единственная причина может быть в том, что вы не верите, что TDD позволит быстрее создавать лучший код.

Я думаю, что кто-то перестает использовать TDD, потому что считает, что он лучше производит плохой код быстрее.

7
ответ дан 3 July 2019 в 13:07
поделиться

IMO, TDD с тестом / кодом / рефакторингом - звучит здорово и весело, но:

  • нет жесткого правила, что это должно выполняться в такой последовательности
  • Много раз мне приходилось писать код, а затем писать тесты и находить интересные самородки, которые я пропустил
  • В других случаях я переходил к циклу «тест> код> рефакторинг» и все равно наслаждался этим.
  • Я думаю, что важным аспектом является наличие модульно-протестированного кода и достаточного покрытия, чтобы обеспечить охват всех важных путей. Порядок его достижения не так важен.

HTH.

РЕДАКТИРОВАТЬ: чтобы прояснить мою точку зрения

  • Хотя я предпочитаю начинать с написания тестов, иногда легче понять ландшафт, написав код (особенно для новых функций и / или новых проектов), а затем написав тесты
  • Но если я занимаюсь рефакторингом кода и / или исправляю ошибки, я сначала проверю, написаны ли тесты и достаточно ли они охватывают то, что делает часть кода. Если нет, то сначала я напишу тест, а затем проведу рефакторинг.
-1
ответ дан 3 July 2019 в 13:07
поделиться

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

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

У меня есть несколько классов, в которых у меня есть чистый модульно протестированный код, но мне кажется, что я не могу продолжить процесс, когда на сцену выходят макеты . Кроме того, раз я вижу: синдром "не слишком ли тривиально написать тест на это".

Издевательства - это одно - ты еще хорошо в них разбираешься? Если вам некомфортно с mock'ами, и вы находитесь в ситуации, когда mock'ы уместны, тогда тренируйтесь, пока - как TDD - вы не станете хорошо с ними.

Что касается «слишком банального» вопроса - не первые пару недель. Просто все время TDD. И когда вы обнаружите, что TDD ведет вас к лучшему дизайну - даже для «слишком тривиального» кода - обратите внимание на это.Подумайте, как бы выглядел ваш код без него. И вы можете обнаружить, что для TDD нет слишком тривиального кода. Или не. Но я считаю, что попробуйте серьезно в течение значительного периода времени, и тогда вы сможете сделать лучший выбор. Разберитесь с этим, а затем оцените.

24
ответ дан 3 July 2019 в 13:07
поделиться

Когда вы находитесь в большом беспорядке унаследованного кода, я нашел Working Effectively with Legacy Code чрезвычайно полезным. Я думаю, это улучшит вашу мотивацию к TDD в целом, даже если речь идет о написании модульных тестов до того, как вы внесете какие-либо изменения в старый унаследованный код. И, судя по интонации вашего вопроса, похоже, что вы придерживаетесь именно такой позиции.

И конечно, как многие другие отметили, дисциплина. Через некоторое время, заставляя себя, вы забудете, почему вы делали это по-другому.

1
ответ дан 3 July 2019 в 13:07
поделиться

TDD - действительно хорошая практика (но в то же время я не думаю, что мы должны пытаться достичь 100% покрытия кода).

Его основные преимущества:

  1. Он заставляет разработчика задуматься об API, потому что ему нужно сначала использовать этот API для написания тестов. На этом этапе очень легко почувствовать, что с вашим API что-то не так (плохие имена методов, многие строки требуются для наиболее распространенных операций, слишком много нечетных проверенных исключений или наоборот, пользователь не имеет возможности обрабатывать предполагаемые исключения). И вы можете его улучшать и менять как хотите, потому что еще никто не использовал.

  2. Вы думаете о том, как должны работать ваши методы. Это часто вызывает некоторые неявные проблемы или недоразумения на ранних этапах.

  3. Когда у вас есть тесты, у вас есть хороший способ измерить процент выполненной работы (т.е. если у вас есть 20 тестов и 15 из них пройдены, то 75% работы выполнено). Для вас как разработчика это важнее, чем для вашей команды или процесса. Вы просто разделяете всю задачу на множество более мелких задач (например, 20) и можете выполнять их одну за другой. Это намного приятнее, чем брать на себя все.

  4. Тесты позволяют поиграть с кодом. Вы можете провести рефакторинг, улучшить производительность и т. Д. И снова, даже если вы все равно этого не сделаете, очень приятно осознавать, что у вас есть возможность это сделать. Это своего рода уверенность, что все хорошо.

Как заставить себя делать TDD? Вам не нужно! Если вы хотите получить все перечисленные преимущества, то вы не заработаете сами - вы просто будете делать TDD с удовольствием и по своей воле. Если вы не нуждаетесь / не хотите / не можете их получить - не делайте этого сейчас.

1
ответ дан 3 July 2019 в 13:07
поделиться

В простом коде прячутся ошибки. В основном я думаю, потому что человеческая природа читать то, что должно было быть там, а не то, что там .

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

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

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

Так что сначала напишите свой тест, а затем код, бит за битом, параллельно. Используйте тесты, чтобы утверждать, что ваш код правильный, и используйте код, чтобы утверждать, что ваши тесты верны (да, может случиться так, что вы уверены, что ваш алгоритм идеален, но тесты по-прежнему не работают, и все потому, что вы допустили глупую опечатку в тесте. Я сделал это сегодня утром).

4
ответ дан 3 July 2019 в 13:07
поделиться

Парная программа, выполняющая TDD (в идеале С кем-то лучше, чем ты),

Даже если это в свободное время

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

Найдите (или запустите) Code Retreat или додзе кодирования с особым акцентом на парное программирование и TDD.

Если ваша компания позволяет вам, организуйте его в рабочее время или, по крайней мере, на месте в вашей компании, даже если это всего час в неделю или во время обеда.

2
ответ дан 3 July 2019 в 13:07
поделиться

Дисциплина.

Примите решение использовать TDD и придерживайтесь его, это полностью вопрос вашей собственной способности посвятить себя процессу и довести его до конца.

4
ответ дан 3 July 2019 в 13:07
поделиться

TDD - это не столько написание тестов первыми. Если все, чего вы хотите, это написать тесты первыми, то вам нужна техника Test-First. Проблема в том, что техника Test-First в вакууме (без TDD) в конечном итоге распадается на что-то, что почти хуже, чем отсутствие тестов вообще.

Вы сами сказали, в чем ваша проблема - :

или в ходе проекта TDD забывается в попытке закончить код быстрее

Однако, если бы вы занимались TDD и признавали всю его ценность, ваша команда поняла бы, что невозможно сделать код быстрее без TDD, поскольку именно он делает процесс программирования быстрым в первую очередь.

Я предлагаю потратить некоторое время на то, чтобы понять, какую ценность он может дать вам, осознав, какие виды артефактов может заменить хороший тест. При настоящем TDD один документ выполняет все следующие роли/потребности:

  1. Тест (работает это или нет?)
  2. Анализ (чего мы пытаемся достичь?)
  3. Дизайн (как мы собираемся этого достичь?)
  4. Спецификация (как мы собираемся этого достичь?)
  5. . )
  6. Спецификация (как мы узнаем, когда закончим?)
  7. Финишная черта (эй, мы закончили!)
  8. Отчет о проделанной работе (эй, они уже закончили?)
  9. Контроль процесса (что делать дальше?)

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

Как только вы четко уяснили эти вещи, вы можете начать беспокоиться о том, как делать TDD.

1
ответ дан 3 July 2019 в 13:07
поделиться

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

Перед тем, как писать производственный код, каждый в команде должен подумать, не снимая головы. Это может быть сложно, поскольку, несмотря на то, что люди могут сказать, что они будут делать, нет никакой гарантии, как только они доберутся до своей клавиатуры.

Некоторым менеджерам может показаться, что TDD - дорогостоящий подход, поскольку я действительно считаю, что кодирование чего-либо может занять немного больше времени (и это то, что видят счетчики bean-компонентов), но это краткосрочная «боль» для длительного - срок выигрыша. Затем у вас есть (надеюсь) хорошо написанный, проверенный код с механизмом, позволяющим обнаруживать ошибки в будущем, когда что-то изменится.

Для тех, кто не убежден, дайте TDD на примере прочитать и попробуйте его для итерации вашего программного обеспечения.

0
ответ дан 3 July 2019 в 13:07
поделиться

Попробуйте практиковать кодовое ката .

Ката предназначено для запоминания. Ученики ката изучают его как форму, не как заключение. Важно не заключение ката, шаги, которые приводят к заключению. Если вы хотите научиться думать так, как я думаю, чтобы разработать способ, который я проектирую, тогда вы должны научиться реагировать на мелочи так, как я реагирую. {{1 }} Заполнение этой формы поможет вам сделать это. Изучая форму, повторяя и повторяя ее, вы подготовите свой разум и тело, чтобы реагировать так, как я отвечаю на минуту факторы, которые приводят к конструктивным решениям.

Кодовое ката дало мне представление о том, как должна выглядеть TDD. Я знаю раньше , когда я начинаю терять ритм, чтобы вернуться к старым привычкам. В этот момент я знаю, что мне нужно делать меньшие шаги, чаще запускать тесты, следить за тем, чтобы я не выполнял рефакторинг под красным цветом и т. Д.

5
ответ дан 3 July 2019 в 13:07
поделиться

Как, по вашему мнению, я должен с этим справляться?

Я предлагаю вам представить ваши модульные тесты как диалоги с объектом (предполагается, что вы программируете на языке с поддержкой ОО, таком как Java, C#, Ruby, PHP и т.д.)

Создайте класс тестового примера, подумайте в методе теста о взаимодействии, которое вы хотите иметь с вашими объектами. Представьте, что вы разговариваете с интеллектуальной машиной, используя метод, который вы передаете своим объектам в качестве глаголов, а затем используйте утверждения для проверки того, что объекты отреагировали так, как вы хотите, чтобы они отреагировали.

Через некоторое время вам может настолько понравиться этот стиль программирования, что вы не сможете представить себе программирование без него ;-)

.
2
ответ дан 3 July 2019 в 13:07
поделиться

Купите « Разработка через тестирование: на примере » Кента Бека и прочтите его.

Затем напишите неудачный модульный тест.

3
ответ дан 3 July 2019 в 13:07
поделиться

Требуется много практики кодирования .. . упражняться.

  • Вы можете изучить и понять концепцию объектно-ориентированного программирования за несколько часов. Но многие программисты признают, что только после двухлетней практики объектно-ориентированного программирования они внезапно почувствовали себя «бегло».

  • Программист на C ++ может легко «выучить C #» за считанные дни. Но по-прежнему требуется немало усилий, прежде чем они станут «бегло» и поймут все последствия всего, что они пишут (вместо того, чтобы быть программистом на C ++, конвертирующим синтаксис в C #).

  • Изначально я научился печатать «двумя пальцами». Это продвинулось до такой степени, что я мог довольно быстро печатать этим методом, но я решил попробовать научиться слепой печати. В течение нескольких недель я заставлял себя преодолевать боль и разочарование от необходимости набирать все очень медленно , используя слепой набор.Это было сложно и требовало настоящей приверженности, потому что каждой строкой, которую я печатал, я просто хотел вывести ее из себя тем способом, который я уже знал, способом, который принесет мне быстрые результаты. Но со временем моя скорость слепого набора текста сравнялась с моей скоростью печати двумя пальцами.

  • Я сопротивлялся соглашениям о префиксе MFC (например, префиксы «m_» и «p»), когда впервые начал работать с MFC. Это казалось уродливым, нелепым и бессмысленным лишним набором текста. Затем я заставил себя использовать эту систему в течение месяца, и по прошествии этого времени я не мог понять, как я когда-либо писал код без этого соглашения об именах - это помогло мне понять код лучше и быстрее и уменьшило количество глупых ошибок.

Так как же развить дисциплину для выполнения TDD? Просто возьмите на себя обязательство заниматься TDD в течение месяца. Это будет медленно. Это будет сложно. Будет заманчиво выговорить несколько строчек «по старинке». Но со временем вы наберетесь опыта и скорости, и работать таким образом станет намного проще и естественнее. Затем вы можете оценить TDD и не-TDD и решить, какой подход работает лучше всего. Вы, наверное, не оглянетесь назад.

1
ответ дан 3 July 2019 в 13:07
поделиться

Это просто:

By learning to think about the "What" __before__ you think about the "How"

Другими словами, подумайте о том, что вы хотите, чтобы делал (интерфейс), а не о том, как вы собираетесь это делать (реализация)

TDD как инструмент проектирования, исходя из моего опыта, действительно помогает вам смотреть на вещи с точки зрения пользователя, а не с точки зрения программиста. Кроме того, я думаю, что TDD помогает вашему разуму на самом деле думать о том, что именно вы пытаетесь сделать, каков ожидаемый результат и т. Д.

Так что в следующий раз, когда вы попробуете «TDD», спросите себя что вы пытаетесь сделать, и просто начните писать код, выражающий ваше намерение.

Пример:

Допустим, кто-то хочет, чтобы вы записали им целочисленный сумматор.

Человек, не имеющий представления о TDD, просто сделает:

int add(int a, int b)
{
  return a + b;
}

Правильный ли приведенный выше код? Конечно да. Но этот подход, основанный на моем опыте, не работает, когда вам нужно написать сложный компонент. (Именно поэтому вы в первую очередь задали этот вопрос; я знаю, я был там раньше (возможно, до сих пор? Lol))

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

Другими словами, если бы кто-то попросил меня написать сумматор, у меня было бы что-то вроде:

void assertOnePlusTwoEqualThree()
{
  assert( add(1,2) == 3 );
}

Обратите внимание, как, даже прежде, чем подумать о том, как должен работать add (), я уже сгладил несколько вещи.То есть, я уже разобрался:

  • интерфейс моего сумматора и входы, и выходы
  • первый тривиальный тестовый пример (юнит-тест бесплатно !!)

затем вы реализовать add ().

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

Точно так же, как если вы всегда хорошо занимаетесь программированием, независимо от сложности, вы подходите к своей работе одинаково .

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

Человеческий разум, ИМО, легче работает с конкретными примерами (контрольными случаями / сценариями), чем с абстрактным мышлением (как что-то реализовать). Наличие тестовых примеров позволяет вашему разуму постепенно узнавать о проблеме, которую вы пытаетесь решить.

Не знать - это нормально (возвращаясь к «традиционным» способам… расслабься, позволь своему разуму приспособиться). Ничего страшного, если он не идеален (написать код реализации - это нормально ...ваш мозг просто пытается во всем разобраться). Просто продолжайте пытаться, продолжайте читать, продолжайте кодировать, но никогда не сдавайтесь! =)

15
ответ дан 3 July 2019 в 13:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: