Недостатки тестовой разработки? [закрыто]

192

Что я потеряю, приняв тестовый дизайн?

Список только негативов; не перечисляйте льготы, написанные в отрицательной форме.

IanL
источник
Я добавил ответ о том, что BDD может смягчить некоторые из этих негативов. Я призываю вас учитывать этот фактор при сборе отрицательных данных, поскольку некоторые из них могут быть устранены и больше не считаются отрицательными.
Килхоффер
25
За разъяснения я не против или за. Я пытаюсь принять обоснованное решение по этому вопросу, но большинство людей, которые защищают TDD, не понимают или не признают негативы.
IanL
1
В названии упоминается «Разработка через тестирование», но в основной части вопроса упоминается «Разработка через тестирование». О каком из этих двух вопросов идет речь? Есть важные, но тонкие различия между ними. Проектирование, основанное на тестировании, позволяет тестам управлять разработкой программного обеспечения. Разработка через тестирование обычно связана с написанием тестов перед производственным кодом (но не обязательно позволяет тестам влиять на дизайн).
Джим Хёрн
3
TDD - это клетка, которая задерживает творческий потенциал разработчика.
Льюис
13
пожалуйста, прекратите закрывать важные вопросы, джеус
Каспер Леон Нильсен

Ответы:

129

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

  • Большое время инвестиций. В простом случае вы теряете около 20% реальной реализации, но в сложных случаях вы теряете гораздо больше.
  • Дополнительная сложность. Для сложных случаев ваши тесты сложнее рассчитать, я бы предложил в таких случаях использовать автоматический ссылочный код, который будет выполняться параллельно в отладочной версии / тестовом прогоне, вместо модульного теста в простейших случаях.
  • Влияние на дизайн. Иногда дизайн не ясен в начале и развивается по мере продвижения вперед - это заставит вас повторить тест, что приведет к большим потерям времени. Я бы предложил отложить модульные тесты в этом случае, пока вы не разберетесь в дизайне.
  • Непрерывная настройка. Для структур данных и алгоритмов черного ящика модульные тесты были бы идеальными, но для алгоритмов, которые имеют тенденцию изменяться, подстраиваться или настраиваться, это может привести к большим затратам времени, которые, как можно утверждать, не оправданы. Поэтому используйте его, когда считаете, что он действительно соответствует системе, и не заставляйте дизайн соответствовать TDD.
Adi
источник
7
Суть (4) заключается в том, что любая система, которая недостаточно четко определена и, вероятно, будет продолжать изменяться в соответствии с изменяющимся визуальным поведением, различными характеристиками искусственного интеллекта, поведенческими алгоритмами и т. Д., Приведет к большим затратам времени на повторные определения тестов, поскольку мы продолжаем на изменение желаемых результатов испытаний.
Ади
12
Правда, но разве это не будет так же без TDD? Без этого вам пришлось бы проводить больше ручного тестирования, которое могло бы столкнуться с той же проблемой.
Слёске
50
Разве «большие инвестиции времени» не помогут вам сэкономить время при разработке вашего решения? Особенно со сложным? Я думаю, это должно сэкономить ваше время. Не думать о фазе обслуживания, когда небольшие изменения могут легко сломать систему. ( или, может быть, я просто наивен в отношении юнит + регрессионных тестов, предотвращающих будущие ошибки )
Роберт Коритник
6
Серхио / Роберт, я очень за то, чтобы провести модульное тестирование для универсальных систем и определенно для компонентов, которые представляют собой самую основу для систем. Сказав это, я бы добавил, что необходимо проводить различие между этими случаями и чрезмерным упрощением реальной жизни, пытаясь утверждать, что каждая система может рассматриваться таким образом. Не все системы могут быть обобщены и упрощены для модульного тестирования, и если вы попытаетесь форсировать характер модульного тестирования в таких системах, вы легко можете потратить гораздо больше времени на исправление ваших модульных тестов, чем на реальное тестирование реальных результатов.
Ади
3
@Adi: Я думаю, что вы не правы. По моему мнению, каждая система может быть протестирована таким образом, это только вопрос самодисциплины.
BlueLettuce16
189

Если вы хотите создать «настоящий» TDD (читай: сначала тестируйте с красным, зеленым, с шагами рефакторинга), то вам также нужно начать использовать макеты / заглушки, когда вы хотите протестировать точки интеграции.

Когда вы начнете использовать mocks, через некоторое время вы захотите начать использовать Dependency Injection (DI) и контейнер Inversion of Control (IoC). Для этого вам нужно использовать интерфейсы для всего (что само по себе имеет много подводных камней).

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

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

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

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

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

Если вы читаете литературу по TDD, всегда есть несколько очень хороших примеров, но часто в реальных приложениях вы должны иметь пользовательский интерфейс и базу данных. Здесь TDD становится действительно трудным, и большинство источников не предлагают хороших ответов. И если они это делают, это всегда включает в себя больше абстракций: фиктивные объекты, программирование на интерфейс, шаблоны MVC / MVP и т. Д., Что опять же требует много знаний, и ... вы должны написать еще больше кода.

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

Thomas Jespersen
источник
7
Используя такие инструменты, как Pex & Moles, вы можете легко избежать написания интерфейсов для каждой мелочи. Родинки вам в этом очень помогут.
Роберт Коритник
24
Похоже на критику модульного тестирования и объектно-ориентированного программирования, а не TDD.
plmaheu
5
На самом деле правильное ** модульное тестирование ** - не только TDD - требует макетов / заглушек. И программирование на основе интерфейса часто является хорошей идеей, то же самое касается шаблонов. Если вы смешаете пользовательский интерфейс и логику, у вас будет плохое время. Если вам нужно проверить взаимодействие с БД, вы все равно можете смоделировать свой DAO для модульных тестов и использовать реальное для интеграционного теста.
TheMorph
1
Я согласен с тем фактом, что один туман обладает знаниями о дизайне и тестировании, прежде чем прыгнуть в tdd. Это очень важно в проектах с новым наймом, поскольку они являются новыми для обоих.
Хитеш Саху
голосовать за мудрость
сабсаб
66

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

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

Эрик З Борода
источник
3
Определенно, это может быть проблемой, однако я вижу заметную разницу в том, насколько сильно на меня это влияет. Все сводится к «написанию тестируемого кода», я думаю.
Роб Купер
2
Скотт, я обычно привожу пример SqlDataSource, встроенный в страницу ASPX. Вы не можете автоматизировать тест для этого. Это просто и выполняет свою работу, всего 1 файл. Тестируемый компонент - это объект MSFT SqlDataSource, и это уже сделано для нас. Нам не нужно делать больше.
Эрик Борода
8
+1 «Вы можете начать принимать проектные решения, основываясь больше на TDD, чем на действительно хороших дизайнерах» - самая большая ловушка TDD ИМХО.
Андраш Шепешази
2
@ ScottSaad проблема IMO заключается в том, что сначала необходимо очертить дизайн, а затем проверить его путем написания тестов и при необходимости исправить. Я видел множество случаев, когда люди ставили под угрозу хороший дизайн, чтобы написать тест. В результате - большая часть системы была покрыта тестами, но дизайн был действительно уродливым. Я думаю , что это происходит потому , что TDD проталкивается к массам , как очень простая методология с следующим заблуждением : if part of the system is covered by tests and they pass, then everything is fine (including design).
Юрий Наконечный
3
@Yura: Интересно, что вы говорите, что люди ставили под угрозу хороший дизайн, просто чтобы иметь возможность писать тесты. На мой взгляд, если бы был хороший дизайн, не было бы необходимости подвергать его опасности. Я когда-то видел такой проект, и кодовая база была кошмаром, но люди думали так же - дизайн великолепен. Я согласен только с той частью, что TDD выдвинут в массы как очень простая методология, однако это полная противоположность. По моему мнению, когда код разработан хорошо, тогда, когда вы вносите одно небольшое изменение, тогда нет шансов затормозить все тесты или их большое количество.
BlueLettuce16
54

Я думаю, что самая большая проблема для меня - ОГРОМНАЯ потеря времени, необходимая для того, чтобы «войти в нее». Я все еще очень в начале моего пути с TDD (см. Мой блог для обновлений моих тестовых приключений, если вам интересно), и я буквально потратил часы, чтобы начать.

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

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

Итак, (IMO) в двух словах:

  • Время, затрачиваемое на обдумывание (то есть на самом деле тестирование ).
  • Новые знания требуют умения писать тестируемый код.
  • Понимание архитектурных изменений, необходимых для обеспечения возможности тестирования кода.
  • Повышение вашего навыка "TDD-Coder", в то же время пытаясь улучшить все другие навыки, необходимые для нашего славного ремесла программиста :)
  • Организация вашей кодовой базы для включения тестового кода без использования вашего рабочего кода.

PS: Если вам нужны ссылки на позитивы, я задавал и отвечал на несколько вопросов, проверьте мой профиль .

Роб Купер
источник
1
К сожалению, первый разумный ответ, который я увидел ...
Даниэль С. Собрал
5
Весьма практичный и простой ответ - +1 для части «Установка разума»
ha9u63ar
50

За те несколько лет, когда я практиковался в разработке через тестирование, я бы сказал, что самые большие недостатки:

Продавать это руководству

TDD лучше всего делать парами. Во-первых, трудно сопротивляться желанию просто написать реализацию, когда вы ЗНАЕТЕ, как написать оператор if / else . Но пара будет держать вас на задании, потому что вы держите его на задании. К сожалению, многие компании / менеджеры не считают, что это хорошее использование ресурсов. Зачем платить двум людям за написание одной функции, если у меня есть две функции, которые нужно сделать одновременно?

Продавая это другим разработчикам

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

Ведение тестового кода вместе с вашим рабочим кодом

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

Написание тестов, чтобы вы покрывали все (100% покрытие кода)

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

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

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

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

оборота касадемора
источник
7
Чем закончилось предложение, заканчивающееся словами "(тест на кашель), затем основной"?
Эндрю Гримм
+1 за проблему продажи. :) Я сейчас нахожусь в новой компании и думаю о том, как создать культуру, которая позволила бы свободно распространять навыки.
Эско Луонтола
2
Как и вы, я считаю, что некоторые консалтинговые компании используют преимущества парного программирования и TDD, чтобы получить больше денег от своих клиентов. Довольно разочаровывает то, как эти клиенты платят за идеи, которые на первый взгляд кажутся разумными, например, два человека думают намного лучше, чем два, или что TDD гарантирует, что каждая строка кода тестируется, но в конце концов они являются лишь оправданием для того, чтобы заставить клиента платить больше для того, что может сделать только один человек.
lmiguelvargasf
24

В вашем первом проекте TDD есть две большие потери, время и личная свобода

Вы теряете время, потому что:

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

Вы теряете личную свободу, потому что:

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

Надеюсь это поможет

Garth Gilmour
источник
1
Я не знаю, потому ли это, что я худший или лучший .. но TDD теряет меня неправильно. Это потому, что слишком рано заставляет меня переходить в режим двойного обслуживания. Каждый раз, когда я изменяю дизайн класса, теперь я должен также изменить контрольные примеры. Я ожидаю и принимаю это от зрелого класса, но не от класса, который я только что написал на прошлой неделе! Также я могу просто сказать, что DI и TDD не очень хорошо поддерживаются такими языками, как Java и C #. Кому-то действительно нужно создать новый язык, чтобы стоимость TDD и DI была буквально нулевой . Тогда у нас больше не будет этого разговора.
Джон Хенкель
14

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

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

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

Chrass
источник
1
Хотя у вас должно быть представление о том, как будет выглядеть архитектура вашей системы, вам не нужно много знать заранее при выполнении TDD. TDD означает, что тесты приводят в движение дизайн, поэтому он будет меняться по мере реализации большего количества тестовых сценариев
casademora
4
Я согласен с вакуумом. Оригинальные руководства по TDD, в которых вы будете писать тест без ЛЮБОГО кода - и получите ошибку компиляции - сумасшедшие.
Мпараз
Это неверное предположение, что вы можете написать тесты один раз и не менять их. Это код, и каждый код требует возможного рефакторинга после внесения изменений. Тесты не исключение. Рефакторинг тестов является обязательным, если вы хотите сохранить их ремонтопригодность.
Роман Коновал
12

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

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

Calum
источник
9

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

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

Тим Салливан
источник
13
Ага - но вот тут и приходит TDTDD. Разработка через тестирование.
Snowcrash
3
Я до сих пор иногда нахожу ошибки в моих тестовых тестах. Так что теперь я практикую TDTDTDD.
HorseloverFat
@SnowCrash +1 Я смотрел в Google, чтобы узнать, сколько времени люди тратят на тестирование своих тестов, а затем я увидел этот ответ. Я официально нашел это, потому что меня интересовало TDTDTDD.
BalinKingOfMoria восстанавливает СМ
1
Я считаю, что будущее (TD) <sup> ∞ </ sup> TDD. Пока у меня есть один файл: он содержит букву «х».
Майк Грызун
Я согласен с @Tim. Убедить участников принять это самая трудная часть.
Олу Смит
7

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

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

Аарон Ли
источник
Я не верю ни в какое положение о здравомыслии, так как я вырос.
Майк Грызун
7

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

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

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

Рон МакМахон
источник
1
Отлично поставлено. Я не мог согласиться больше. Для меня тесты, безусловно, не помогают описать реальные определения проблем более высокого уровня. Хорошая документация доказала свою ценность снова и снова. Как тех. Промышленные возрасты, проверенные временем понятия, следует обходиться без особой осторожности. Самодокументированный код - нелепое понятие. Я действительно верю в создание прототипов, рефакторинг и гибкость, которая заключается в том, чтобы никогда не определять проблему с самого начала. Однако, по иронии судьбы, недопущение чрезмерного определения проблемы на старте делает заглушку для TDD минным полем.
wax_lyrical
1
Я думаю, что это несправедливо. Хорошая практика TDD осуждает магические числа и непонятные тесты. Тесты должны быть простыми и, как правило, более читабельными, чем сам ваш рабочий код. ваши тесты являются документацией. убедитесь, что они похожи на это. этот ответ выглядит как выражение «документация - это зло, потому что иногда люди пишут действительно плохую документацию» или «классы плохие, потому что я видел некоторые классы бога, с которыми было трудно иметь дело».
Сара
6

Я столкнулся с несколькими ситуациями, когда TDD сводит меня с ума. Чтобы назвать некоторые:

  • Ремонтопригодность сопровождения:

    Если вы работаете на большом предприятии, есть много шансов, что вам не нужно писать тестовые примеры самостоятельно, или, по крайней мере, большинство из них написаны кем-то другим, когда вы входите в компанию. Функции приложения время от времени меняются, и если у вас нет системы, такой как HP Quality Center, чтобы отслеживать их, вы сразу же сходите с ума.

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

  • Сложность автоматизации тестирования:

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

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

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

Самая большая проблема - это люди, которые не знают, как правильно писать модульные тесты. Они пишут тесты, которые зависят друг от друга (и они отлично работают при работе с Ant, но внезапно терпят неудачу, когда я запускаю их из Eclipse, просто потому, что они работают в другом порядке). Они пишут тесты, которые ничего не тестируют - они просто отлаживают код, проверяют результат и превращают его в тест, называя его «test1». Они расширяют область применения классов и методов только потому, что им будет проще писать модульные тесты. Код модульных тестов ужасен, со всеми классическими проблемами программирования (сильная связь, методы длиной 500 строк, жестко запрограммированные значения, дублирование кода), и это адское обслуживание. По какой-то странной причине люди относятся к юнит-тестам как к чему-то хуже "реального" кода, и они не не заботятся об их качестве вообще. :-(

rmaruszewski
источник
4

Вы теряете много времени, потраченного на написание тестов. Конечно, это может быть сохранено к концу проекта, быстрее обнаруживая ошибки.

Джоэл Коухорн
источник
Это действительно отрицательный или хитрый способ заявить о положительном.
Янв
3

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

Если вы работаете в компании, которая платит вам KLOC (или выполненными требованиями - даже если они не проверены), держитесь подальше от TDD (или проверок кода, или парного программирования, или непрерывной интеграции и т. Д. И т. Д. И т. Д.).

Васко Дуарте
источник
3

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

Вы теряете возможность писать сотни или тысячи строк кода перед его запуском.

Вы теряете возможность учиться через отладку.

Вы теряете гибкость при отправке кода, в котором вы не уверены.

Вы теряете свободу крепко соединять свои модули.

Вы теряете возможность пропустить написание низкоуровневой проектной документации.

Вы теряете стабильность, которая приходит с кодом, который все боятся изменить.

Uncle Bob
источник
1
Зависит от вашего определения «доставить решение вовремя» - это «любое старое, частично сломанное решение вовремя» или «доставить работающее решение вовремя». Вы, безусловно, теряете способность доставлять частично сломанные решения вовремя. Что касается скорости разработки - мне нравится показатель «истекшее время между запуском dev и неделей безошибочного развертывания в реальном времени». Если вы измеряете это справедливо, даже на стоп-кусках работы без TDD трудно вообще остановить часы.
Дафидд Рис
47
-1, это именно то, что ОП сказал, что он не хочет.
erikkallen
1
Много верных высказываний, но: что сказал Эриккален. -1.
j_random_hacker
@ j_random_hacker говорит, что хакер ... LOL
Дэн
только третье утверждение является законным «учиться на отладке потеряно»
ЯГ
2

Я второй ответ о начальном времени разработки. Вы также теряете способность комфортно работать без безопасности испытаний. Я также был описан как чокнутый TDD, так что вы можете потерять несколько друзей;)

Крис Канал
источник
2

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

Marce
источник
2

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

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

Это, конечно, обоюдоострый меч. Если вы тратите все свое время на разработку для всех мыслимых, мыслимых, X, Y и Z, которые может когда-либо захотеть пользователь, вы неизбежно никогда ничего не завершите. Если вы что-то завершите, никто (включая вас) не сможет понять, что вы делаете в своем коде / дизайне.

Дуг Т.
источник
Подумайте об этом, вы, скорее всего, в конечном итоге будете проектировать под конкретные тестовые случаи, поэтому вы не станете креативными и начнете думать, что «было бы здорово, если бы пользователь мог выполнять X, Y и Z». - По-моему, с точностью до наоборот. Если вы пишете модульные тесты, вы задаетесь вопросом о различных бизнес-кейсах, а это означает, что вы креативны, и это позволяет предвидеть что-то непредвиденное. Однако все это творчество не важно, если в вашей реализации есть ошибки.
BlueLettuce16
1

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

Vargen
источник
Это распространенная проблема. Я склонен над ними издеваться с жестко закодированными объектами, а затем тестировать базу данных отдельно. Тогда ваш бизнес-уровень должен работать только со статическими данными, а ваш DAL будет затем тестироваться в контролируемой среде (где вы можете записать данные в него и т. Д.)
Роб Купер
1

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

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

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

Дейв Манн

Дейв Манн
источник
1

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

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

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

В целом, хотя недостатки становятся решаемыми, когда люди становятся квалифицированными, и вы в конечном итоге абстрагируетесь от «вонючего» кода и получаете более стабильную систему.

Питер Гиллард-Мосс
источник
1

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

aerlijman
источник
1
  • модульное тестирование - это больше кода для написания, тем самым более высокая стоимость разработки
  • это больше кода для поддержки
  • требуется дополнительное обучение
Боб Диззл
источник
1

Хорошие ответы на все. Я бы добавил несколько способов избежать темной стороны TDD:

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

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

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

Майк Данлавей
источник
Случайные тесты могут периодически прерываться, что затрудняет их повторение
Дэвид Сайкс
@DavidSykes: Всякий раз, когда вы делаете случайный тест, вы записываете параметры, чтобы в случае сбоя вы могли повторить его или повторить позже, даже если он не дал сбоя. Дело в том, что вы не должны придумывать контрольные примеры. Если вы похожи на меня, вы инстинктивно стремитесь к безопасным тестам.
Майк Данлавей
0

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

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

Джейсон Коэн
источник
9
Все частные методы должны быть проверены с помощью открытых методов, которые в любом случае существуют.
Гарри Шатлер
Это не возможно со всеми классами. Иногда вы не хотите макетировать все зависимости и т. Д., А просто хотите протестировать служебный метод.
Джейсон Коэн
+1, это правда. Добавьте к этому требование иногда добавлять геттеры / сеттеры в частные поля, чтобы иметь возможность правильно настроить и прочитать состояние для модульного теста, даже если это состояние должно быть приватным для класса.
erikkallen
Подумайте о том, чтобы написать свои тесты, как если бы это был документ с требованиями к жизни. Тогда вы увидите свет. Также прочитайте тестовые шаблоны XUnit.
Скотт Нимрод
0

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

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

Kilhoffer
источник
Абсолютно. Вы должны учитывать BDD при оценке TDD.
user9991 15.09.08
Кажется, BDD = развитие,
основанное на
0

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

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

Квай
источник
0

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

Его девизом был рефакторинг, рефакторинг, рефакторинг. Я понял, что рефакторинг означает «не планировать заранее».

Джек Б. Проворный
источник
-1

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

Моуна Шейхна
источник
Я занимаюсь разработкой уже 36 лет, и теперь этот пост может дать вам несколько полезных советов: stackoverflow.com/questions/738539/tdd-how/45971814#45971814
user2288580