Действительно ли разработка, основанная на тестировании (TDD), принесла пользу проекту в реальном мире?

36

Я не новичок в кодировании. Я кодирую (серьезно) уже более 15 лет. У меня всегда было некоторое тестирование для моего кода. Однако за последние несколько месяцев я изучал проектирование / разработку на основе тестов (TDD) с использованием Ruby on Rails . Пока что я не вижу выгоды.

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

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

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

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

Итак, мне просто интересно, после всех этих лет, есть ли у нас, наконец, какие-нибудь примеры, показывающие, что выплата реальна? Кто-нибудь на самом деле унаследовал или вернулся к коду, который был разработан / разработан с использованием TDD, имеет полный набор модульных тестов и действительно ощутил отдачу? Или вы обнаружили, что потратили так много времени, пытаясь выяснить, что тестирует тест (и почему это важно), что вы просто выбросили весь беспорядок и погрузились в код?

Джеймс
источник
1
Это сэкономило мне еще несколько раз: потому что мы много людей в одном проекте, потому что обновления gem могут иметь некоторые неизвестные побочные эффекты, потому что, если все зеленое и у меня есть ошибка, я знаю, где не стоит искать его root.
до
4
Приятно читать: 37signals.com/svn/posts/3159-testing-like-the-tsa
апедивинг
3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtest Вот история от дяди Боба о реальной ситуации в мире, с которой он столкнулся.
Хакан Дериал
1
Сначала я думал, что тесты будут хороши для того, чтобы узнать, где нет ошибок, но я быстро понял, как @Hakan указал в статье дяди Боба, в общем, это происходит потому, что вы пропустили тестовый пример. Что делает эти тесты довольно бесполезными. Фактически, эта статья подчеркивает, что постепенное развитие - это то, что работает.
Джеймс
1
«Я обнаружил, что трачу значительно больше времени на отладку своих тестов, чтобы они сказали, что я на самом деле имею в виду, чем на отладке реального кода» : но разве это не то преимущество? После этого вы все еще тратите много времени на отладку «реального кода»? Сторонники TDD утверждают, что время, потраченное на поиск способа сделать ваш код тестируемым, на самом деле является разработкой, которая принесет пользу вашему коду.
Андрес Ф.

Ответы:

26

Эта статья демонстрирует, что TDD увеличивает время разработки на 15-35% в обмен на снижение плотности дефектов на 40-90% в других аналогичных проектах.

Статья ссылается на полный текст статьи (pdf) - Начиаппан Нагаппан, Э. Майкл Максимилиен, Тирумалеш Бхат и Лори Уильямс. «Реализация улучшения качества с помощью тестовой разработки: результаты и опыт четырех промышленных команд». ESE 2008 .

АннотацияРазработка через тестирование (TDD) - это практика разработки программного обеспечения, которая использовалась спорадически на протяжении десятилетий. С помощью этой практики инженер-программист ежеминутно переключается между написанием провальных модульных тестов и написанием кода реализации для прохождения этих тестов. Разработка с использованием Testdrive недавно вновь стала критически важной практикой гибких методологий разработки программного обеспечения. Однако мало эмпирических данных подтверждает или опровергает полезность этой практики в промышленном контексте. Тематические исследования были проведены с тремя группами разработчиков в Microsoft и одной в IBM, которые приняли TDD. Результаты исследований показывают, что плотность дефектов перед выпуском четырех продуктов снизилась на 40-90% по сравнению с аналогичными проектами, в которых не использовалась практика TDD. Субъективно,

Полная статья также кратко суммирует соответствующие эмпирические исследования TDD и их результаты высокого уровня (раздел 3 Связанные работы ), в том числе Джордж и Уильямс 2003, Мюллер и Хагнер (2002), Erdogmus et al. (2005), Müller and Tichy (2001), Janzen и Seiedian (2006).

комар
источник
2
В ходе обсуждения Meta.StackOverflow , не могли бы вы добавить дополнительную информацию из статьи, которая может иметь отношение к любителю, а также будущим людям, которые найдут этот вопрос?
Томас Оуэнс
2
@ThomasOwens, я думал, что вывод («TDD добавляет 15-35% времени разработки в обмен на снижение плотности дефектов на 40-90%») была дополнительной информацией, которая отвечает на первоначальный вопрос <_ <
4
Это сообщение было помечено как не содержащее достаточной информации. Я еще не читал газету, но похоже, что люди хотят, чтобы в текст ответа было добавлено больше информации. Возможно, обсудите больше о конкретных условиях, используемых в исследовании?
Томас Оуэнс
99% всей статистики являются вымышленными. : P Но на самом деле речь идет о контексте. В какой команде? Большая стая посредственных разработчиков Java? Да, я верю, что TDD поможет им с производительностью. Но это не означает, что обладание архитектурными навыками для проектирования и оценки надежного кода в первую очередь не помогло бы им еще больше, и IMO, первый тестовый TDD, мог бы очень легко помешать им когда-либо научиться делать это должным образом. И да, я слышал, что это помогает с дизайном. В определенной степени, это, вероятно, правда, но это все еще неспособность признать и помощь группы для основной проблемы IMO.
Эрик Реппен,
было бы неплохо, если бы из цифровой библиотеки ACM были перечислены еще какие-то статьи или были добавлены ключевые слова для использования в поисковой системе. нам нужно больше строгости в наших ответах, когда речь идет о гибкой и TDD
Рудольф Олах
16

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

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

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

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

Но написание юнит-тестов - это навык, который нужно освоить и освоить, как и любой другой навык программирования. Когда я начал заниматься TDD, у меня было 12 лет профессионального опыта в программировании, и я был очень опытным программистом. Я думал, что написание больших наборов тестов для системного кода будет простой вещью. Но по мере роста объема тестового кода, изменения различных частей системы и необходимости изменения существующих тестов я понял, что структурирование и написание модульного теста сами по себе являются навыком, который необходимо изучать и осваивать. Также не весь код одинаково тестируем. Системный код должен быть очень слабосвязанным, чтобы его можно было эффективно тестировать. На самом деле изучение TDD помогло мне сделать системный код более свободным.

Но моя текущая эффективность в работе TDD основана на сочетании как умения писать модульные тесты, так и овладения технологией, в которой реализована система (в данном случае C #).

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

Но насколько хорошо это работает на реальных проектах?

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

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

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

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

Пит
источник
9

Мы получили огромную пользу.

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

Наша платежная система имеет тысячи модульных и интеграционных тестов. Эти тесты дают нам уверенность в нашей способности обрабатывать платежи. Ты хочешь быть уверен, что твои машины работают, не так ли? Мы хотим быть уверены, что не потеряем свой бизнес, потому что не можем обрабатывать платежи.

Покрытие кода дает вам эту уверенность. Конечно, этого недостаточно, но это очень хорошее начало.

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

Лично мне трудно написать какую-либо логику перед написанием тестов. Сказав это, мне понадобилось немного времени, чтобы начать думать в стиле TDD.

Справочник по Visa PCI: http://usa.visa.com/merchants/risk_management/cisp_merchants.html

CodeART
источник
3
«Мы вернемся и в конце концов решим эти проблемы». - вероятно, нет ... нет, если только они не сумеют ударить тебя какой-нибудь ужасной ошибкой Эти области станут основой для всего остального и будут направлять весь дизайн вперед, потому что никто не захочет инвестировать ресурсы, чтобы переделать их, и никто не захочет форсировать любые изменения, которые могут сделать что-то плохое. Бывает каждый раз: P
Эдвард Стрендж
Вы догадываетесь, когда я рассказываю вам, что происходит внутри компании. Когда мы фиксируем, мы можем зафиксировать код с 70% охватом кода. Это постоянно увеличивается за счет CI свинца. В течение нескольких месяцев минимальный порог покрытия кода будет увеличен на небольшой процент. После этого не будет никакого выбора, кроме как вводить больше тестов.
CodeART
7

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

Я занимаюсь разработкой Killer Sudoku Solver для школы около 3 месяцев, в нем используется множество «стратегий» для устранения возможностей и решений. Дело в том, что ошибка в возможности может быть фатальной и привести к проблеме для решения судоку, потому что когда какая-то возможность удаляется, вы больше не пробуете ее, и если это было решением, программа не может решить сетка больше.

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

А стратегии, применяемые к определенной сетке, довольно «случайны», то есть вы не будете использовать все на определенной сетке.

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

Cydonia7
источник
2
Я чувствую, что этот вопрос вначале больше задевает, а потом реализует стратегию. Тесты, конечно, полезны для отладки приложений, где было бы утомительно проверять каждую возможность самостоятельно.
Алекс Хоуп О'Коннор
6

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

Другими словами, TDD помогает в разработке вашего API.

По моему опыту, это приводит к лучшим API, что, в свою очередь, дает лучший код.


РЕДАКТИРОВАТЬ: Как я уже писал, это было «в моем опыте», то есть при написании «проектов реального мира», но, к сожалению, это с закрытой базой исходного кода, я не могу позволить миру увидеть. Из комментариев я могу понять, что это именно то, о чем действительно просят, а не просто подтверждение существования таких проектов.

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

В тестовых примерах используются версии спецификации, и вы очень легко можете увидеть, как вызывать ваш API. Это, пожалуй, единственная наиболее полезная форма «HOW» -документации, которую я видел до сих пор (сравните с «WHY» -документацией, такой как JavaDoc), поскольку вы уверены, что она верна (в противном случае тест не пройдёт).

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


источник
8
Этот ответ, похоже, совершенно не связан с вопросом, поскольку вопрос требует примеров из реального мира . Но так как три человека думали, что «этот ответ полезен», я должен что-то упустить.
3
Согласен, но мне не хватает репутации, чтобы понизить голосование. Это просто «TDD дает лучшие результаты» без примера проекта, основанного на TDD, в поддержку этого ответа, которого я хотел избежать.
Джеймс
Теперь, когда со мной согласились несколько человек, смею понизить голос. Кто-нибудь из пользователей или автор, пожалуйста, подойдите и скажите нам, почему это хороший ответ?
@delnan "Я смею понижать голос" - интересный выбор слов. Редактирование выпало на ваш вкус?
Да, я убрал свое пониженное голосование теперь, когда заметил это.
5

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

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

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

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

Вы сказали следующее в своем вопросе:

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

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

Если тесты не могут быть упрощены, то один этот факт говорит о том, что с тестируемым кодом что-то не так. Например, если в вашем классе есть длинные методы, методы с большим количеством операторов if / elseif / else или switch или большое количество методов, которые имеют сложные взаимодействия, определяемые текущим состоянием класса, тогда тесты по необходимости должны быть чрезвычайно сложными. обеспечить полное покрытие кода и проверить все возможности. Если ваш класс имеет жестко запрограммированные зависимости от других классов, это снова увеличит количество обручей, к которым вам нужно будет перейти, чтобы эффективно протестировать ваш код.

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

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

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

TL: DR. Да, они помогают в реальном мире, но это инвестиции. Преимущества становятся очевидными позже.

GordonM
источник
1
Я купил эту логику несколько месяцев назад. Мне нравится идея, лежащая в основе TDD, я просто нахожу реальность немного смущающей. Кроме того, я заметил, что даже здесь нет реальных примеров, когда наследование проекта на основе TDD окупилось. Вы действительно вернулись к старой кодовой базе, которая имела кучу модульных тестов и окупилась?
Джеймс
К сожалению, нет, потому что никто другой, кажется, не создает модульные тесты, по крайней мере, ни для какого кода, который я унаследовал от предыдущих разработчиков. Моя жизнь была бы намного проще, если бы они это сделали. Я бы посоветовал вам почитать книгу по ссылке, в которой есть примеры из реальной жизни, хотя она предназначена для PHP, а не для Rails. amazon.com/…
GordonM
Я большой критик общего пользования, но я бы никого не осудил за использование этого подхода во встроенной или критической финансовой системе.
Эрик Реппен
4

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

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

  • QA сообщает о гораздо меньшем количестве ошибок, поэтому мы экономим на ремонте нашего кода после выпуска. Это потому, что TDD не позволяет писать код без теста, поэтому охват кода намного лучше.

  • Я могу выполнять мой (производительный) код гораздо чаще и быстрее, потому что мне не нужно запускать весь сервер приложений. Запуск модульного теста происходит на порядок быстрее. Конечно, я получаю от этого пользу только тогда, когда тест уже выполним, когда я хочу опробовать продуктивный код. Когда тесты приходят позже, это преимущество пропускается.

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

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

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

Wolfgang
источник
Качество бесплатно!
MathAttack
2
Плохое качество дорого!
Вольфганг
3

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

Дауд говорит восстановить Монику
источник
2

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

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

  • Принуждение дизайна, ориентированного на разделение и повторное использование (все должно быть повторно использовано в модульном тесте).
  • Предоставление платформы для разработки кода небольшими блоками и модулями, чтобы мне не нужно было все выяснять и завершать, прежде чем запускать простой тест типа «Скомпилирует ли и даже вводит».
  • Обеспечение платформы быстрого тестирования для внесения изменений, когда люди требуют изменений функций, которых я не ожидал.

Примером этого более позднего бита является проект, над которым я сейчас работаю, руководитель которого внезапно решил ПОЛНОСТЬЮ переписать протокол связи, который он использовал по большей части по 0 причинам. Я смог отреагировать на это изменение за 2 часа, так как я уже отделил это от всего остального и мог работать над ним полностью независимо до самого последнего, связать его и интегрировать тестировать его на шаге. Большинство моих коллег, вероятно, занимались бы этим в течение дня или более, потому что их код не был бы отделен, и они менялись бы здесь, там, везде ... компилируя все это ... интеграционное тестирование ... повторить, повторить ... Это займет намного больше времени и далеко не так стабильно.

Эдвард Стрендж
источник
2

Ответ - да. В моей компании мы разрабатываем приложение на C ++ более 20 лет. В прошлом году мы попали в TDD в некоторых новых модулях, и количество дефектов значительно снизилось. Нам так понравилось, что некоторые из нас даже добавляют тесты в унаследованный код каждый раз, когда мы что-то там меняем.

Более того, весь модуль был завершен от начала до конца, проходя через производство, без каких-либо ошибок (и это тоже критический модуль). Таким образом, его разработка проходила быстрее, чем обычно, потому что в противном случае обычно случалось бы, что модуль был бы «завершен», только чтобы 4-5 раз возвращаться из бета-тестирования для исправления ошибок. Это было существенное улучшение, и разработчики были более довольны новым процессом.

Я не так много сделал в Rails TDD, но я многое сделал в C ++, C #, Java и Python. Я могу сказать вам, что это определенно работает. Я предполагаю, что вы тратите много времени на обдумывание имен тестов, потому что вы недостаточно уверены в себе. Сначала напишите свой тест, но пусть ваше творчество течет ...

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

Время для чаевых

Совет № 1

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

Совет № 2

Начните новые тесты классов с помощью простого теста «canCreate», просто чтобы сконцентрировать свое внимание в правильном направлении, как в «Хорошо, я сейчас работаю над этим классом ... правильно».

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

И помни

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

Дайте еще один шанс. И позвольте мне порекомендовать посмотреть Чистые Коды , особенно те, которые касаются TDD.

Ям Маркович
источник
1

Реальный мир нетривиальный пример:

Мне пришлось написать функцию преобразования структуры данных. Входными данными будет структура данных (фактически вложенная структура данных, очень похожая на дерево), а выходными данными будет аналогичная структура данных. Я не мог представить себе реальную трансформацию в своем уме. Одним из главных преимуществ TDD (для меня, в любом случае) является принудительное выполнение шагов ребенка, если вы не знаете, как действовать (см. Кент Бекс "TDD by Example"). Поскольку я не знал, куда это идет, я начал с простых базовых случаев, таких как пустые или тривиальные входные данные, и перешел к более сложным случаям, пока не решил, что все их охватил. В итоге у меня был рабочий алгоритм и тесты, которые это доказали. Тесты не только доказывают, что моя реализация работает прямо сейчас, но и не дают мне ничего испортить позже.

EricSchaefer
источник
-1

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

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

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

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

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

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

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

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

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

Rosenfeld
источник
это даже не пытается ответить на заданный вопрос: «у нас наконец есть какие-нибудь примеры, показывающие, что выплата реальна? Кто-нибудь на самом деле унаследовал или вернулся к коду, который был разработан / разработан с использованием TDD и имеет полный набор модульных тестов и на самом деле почувствовал отдачу? "
комнат
1
Он отвечает, но так как вы не разделяете мое мнение, вы даете ему -1 :) В принципе, любой, кто не будет пытаться показать значения TDD, даст нежелательный ответ с вашей точки зрения;) Позвольте мне угадать , Вы евангелизатор TDD, верно? :) Кстати, реальный вопрос автора - окупается ли TDD или нет. Вам не нужно практиковать TDD, чтобы ответить на это. Фортран окупается за написание веб-приложений? Вы пытались, прежде чем ответить?
Розенфельд
У меня нет мнения по поводу TDD, и я не использую голоса как нравится / не нравится (это сайт вопросов и ответов, а не Facebook). На мой взгляд, этот «ответ» просто не отвечает на заданный вопрос, ни положительно, ни отрицательно
комнат
С моей точки зрения, это не технический вопрос, например, «как мне сделать X с nginx?». Есть правильные ответы на подобные вопросы, но не на качественные и субъективные вопросы, подобные этому, когда автор действительно хочет узнать мнение других о TDD и стоит ли оно того. Это была моя попытка показать свою точку зрения. Я понятия не имею, как ответ может быть правильным, поскольку все они кажутся мне личным мнением. Вы не можете эффективно измерить, стоит ли TDD или нет. Любые статьи, пытающиеся это сделать, в корне неверны.
Розенфельд
«Этот сайт весь тур получать ответы Это не форум ....»
комар