it-swarm-ru.tech

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

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

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

191
IanL

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

  • Большие затраты времени. В простом случае вы теряете около 20% реальной реализации, но в сложных случаях вы теряете гораздо больше.
  • Дополнительная сложность. Для сложных случаев ваши тесты сложнее рассчитать, я бы предложил в таких случаях попробовать использовать автоматический ссылочный код, который будет выполняться параллельно в отладочной версии/тестовом прогоне, вместо модульного теста простейших случаев.
  • Влияние на дизайн. Иногда дизайн не ясен в начале и развивается по мере продвижения вперед - это заставит вас повторить тест, что приведет к большим потерям времени. Я бы посоветовал отложить модульные тесты в этом случае, пока вы не разберетесь в дизайне.
  • Непрерывная настройка. Для структур данных и алгоритмов "черного ящика" модульные тесты были бы идеальными, но для алгоритмов, которые имеют тенденцию изменяться, настраиваться или настраиваться, это может привести к большим затратам времени, которые, как можно утверждать, не являются оправданный. Так что используйте его, когда вы думаете, что он действительно соответствует системе, и не заставляйте дизайн соответствовать TDD.
124
Adi

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

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

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

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

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

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

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

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

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

184
Thomas Jespersen

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

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

66
Eric Z Beard

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

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

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

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

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

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

54
Rob Cooper

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

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

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

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

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

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

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

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

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

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

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

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

49
casademora

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

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

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

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

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

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

24
Garth Gilmour

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

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

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

14
Chrass

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

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

12
Calum

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

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

9
Tim Sullivan

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

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

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

7
Ron McMahon

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

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

7
Aaron Lee

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

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

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

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

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

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

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

6
Martin08

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

5
rmaruszewski

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

4
Joel Coehoorn

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

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

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

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

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

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

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

Вы теряете звание "хакер".

4
Uncle Bob

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

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

3
Vasco Duarte

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

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

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

2
Doug T.

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

2
Chris Canal

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

1
MarcE

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

1
Vargen

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

1
aerlijman

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

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

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

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

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

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

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

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

Дейв Манн

1
Dave Mann

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

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

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

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

1
Peter Gillard-Moss

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

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

0
Jack B Nimble

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

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

0
Kilhoffer

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

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

0
Jason Cohen

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

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

0
qui