Чуть больше года назад мне посчастливилось взять 9-месячный перерыв в работе. Я решил, что в то время я буду оттачивать свои навыки C #. Я начал работать над кучей проектов и заставил себя следовать TDD.
Это был довольно поучительный процесс.
Сначала это было непросто, но со временем я научился писать более тестируемый код (который, как выясняется, обычно является более твердым кодом), и в процессе я также оттачивал свои навыки проектирования ОО.
Теперь я вернулся в рабочую силу и заметил нечто странное.
Я предпочитаю не следовать TDD.
Я считаю, что TDD замедляет меня и фактически усложняет разработку чистого приложения.
Вместо этого я принял немного (очень) другой подход:
- Выберите вертикальный кусок работы
- Разработать функционирующий прототип
- Рефакторинг пока все хорошо и аккуратно
- Расслабьтесь и оцените красивый твердый и тестируемый код, который я написал.
Вы, возможно, заметили, что шаг 1 не был «определите публичную поверхность моей тестовой цели», а шаг 2 не был «тестом bejesus вне указанной публичной поверхности». Возможно, вы также заметили, что ни один из шагов не включает тестирование. Я пишу тестируемый код, но я не тестирую его ... пока что.
Теперь я хотел бы прояснить, что на самом деле я не отказываюсь от каких-либо испытаний. Код, который я пишу, работает . Это работает, потому что я проверяю это вручную.
Я также хотел бы прояснить, что я не отказываюсь от всех автоматических тестирований. Это где мой процесс отличается. И именно поэтому я задаю этот вопрос.
TDD в теории. Не на практике.
Мой процесс немного изменился, и я нашел баланс между TDD и отсутствием тестов, которые я считаю очень продуктивными и в то же время достаточно безопасными. Это выглядит следующим образом:
- Реализуйте рабочий вертикальный фрагмент работы с учетом тестирования, но не пишите никаких тестов.
- Если в будущем (например, через месяц) этот срез нуждается в модификации
- Написать модульные тесты, интеграционные тесты, поведенческие тесты и т. Д., Которые гарантируют правильность работы
- Изменить код
- Если этот срез не нуждается в модификации,
- Ничего не делать
Просто переложив бремя написания тестов от написания кода до его модификации, я смог создать гораздо более работающий код. И когда я приступаю к написанию тестов, я пишу гораздо меньше их, но покрываю почти столько же (более высокий ROI).
Мне нравится этот процесс, но я обеспокоен тем, что он может плохо масштабироваться. Его успех зависит от того, как разработчики старательно пишут тесты, прежде чем что-то изменить. И это кажется довольно большим риском. Но TDD имеет тот же риск.
Итак, я иду в ад [BT] DD, или это обычная форма прагматического кодирования и тестирования?
Я хотел бы продолжать работать таким образом. Что я могу сделать, чтобы этот процесс работал в долгосрочной перспективе?
Заметка:Я являюсь единственным разработчиком своих проектов и отвечаю за все: сбор требований, проектирование, архитектуру, тестирование, развертывание и т. Д. Я подозреваю, что именно поэтому мой процесс работает.
источник
If that slice doesn't need modification
. lizkeogh.com/2012/06/24/beyond-test-driven-developmentОтветы:
Чтобы процесс работал в долгосрочной перспективе, я писал бы тесты во время написания кода.
Что может показаться противоречащим вашему подходу. Тем не менее, вы задали вопрос, поэтому я дам вам свое мнение:
Вам не нужно писать тесты перед кодом. забудь эту чистоту. Однако вы хотите написать тесты в это время.
Как только у вас есть работающий код, вы немного его подправили, исправили некоторые ошибки (мы говорим о временной шкале часов здесь), вы достигли максимальной степени знания того, что делает код. Это прекрасное время для написания тестов, которые фиксируют ваши знания.
Если оставить это до позднего времени, знание (естественно) со временем уменьшится.
Это также означает, что если вы когда-нибудь уйдете, и если кто-то другой возглавит вас, у вас не будет немедленного технического долга за отсутствие документирования (через тесты), что и для чего.
Больше всего «когда-нибудь» может не наступить. Вас могут либо сбить автобус, либо вы сядете в автобус для новых приключений.
Наконец, ручное тестирование не масштабируется и часто не охватывает все устройства, используемые конечным пользователем.
источник
Хотя TDD сложно реализовать на 100%, в вашем подходе есть недостаток
Реализация рабочего вертикального среза работы
1.1 проходит 1 год ....
1.2 Новый разработчик начинает работу над проектом
Если этот срез нуждается в модификации
2.3 Разбор имен методов и параметров стиля «Чистое кодирование» «GetUnicorn (colourOfUnicorn)»
2.4 Прочитайте xml комментарии 'Получает золотого единорога (для верховой езды) (obvs)'
2.5 Выследить оригинального разработчика
2.6 Надеюсь, они помнят, что должен делать код
2.7 Заставьте их объяснить все это
Написать модульные тесты, интеграционные тесты, поведенческие тесты и т. Д., Которые , как мы надеемся, гарантируют, что часть работы верна
Я думаю, что вы правильно определили, что модульные тесты действительно показывают свою ценность, когда требуются модификации.
источник
Я согласен как с Дэниелом Холлинрейком, так и с Юаном, что первый ключевой момент, почему ваш тест «только для изменения» работает хорошо:
и что вероятным вторым ключевым моментом является:
Я не думаю, что TDD дает огромный прирост производительности для индивидуальных программистов, и это может не сильно улучшить качество вашего кода, если вы уже пишете хороший чистый код.
Тем не менее, TDD наверняка улучшит качество кода плохих / неопытных / устаревших программистов, особенно когда придет время модифицировать код, не нарушая ничего другого. И даже более того, если человек, изменяющий код, - это не тот человек, который изначально написал код, или между ними прошло несколько месяцев.
Другими словами, я думаю, что TDD - это не только хорошая практика для улучшения качества вашего кода (как вы сами это признаете), но и (и что более важно) своего рода хеджирование, когда вы работаете со средними или посредственными программистами (скажем, из другой отдел или другая компания), что гораздо более распространенная ситуация, чем работа соло.
источник
Для меня ключевым моментом является следующее:
Это работает для вас, и вы создаете хороший чистый код (я полагаю!). Единственное, что я бы сказал, что вам нужно сделать, это создать тестовую систему, чтобы другие разработчики могли прийти и быть уверенными в внесении изменений. Кроме того, тестовый набор обеспечивает согласованность в поведении кода.
Я думаю, что ваш подход похож на мой. Я обычно являюсь единственным разработчиком своих проектов. Я обнаружил, что оценка TDD позволила мне писать меньшие функции и более чистый код, но я добавляю тесты, в то время как пишу код как набор тестов. Таким образом, по мере развития кода и изменения его функциональных возможностей, я могу быть достаточно уверен в внесении изменений.
Вторая причина написания тестов заключается в том, что я чувствую, что они являются формой документации. Они могут объяснить мои соображения, почему была создана функция. Но здесь я больше думаю о развитии, управляемом поведением.
источник
Модульное тестирование - это решение проблемы поддержки кода. Хотя есть люди, которые говорят, что они пишут код быстрее с TDD, а не без него, я не удивлен, что вы можете писать больше нового кода без написания тестов.
Проблемы, которые я вижу в практике написания тестов непосредственно перед тем, как вы их измените:
Мне часто нужно вносить изменения в спешке
В то время как вы можете сэкономить время в целом, написав тесты только тогда, когда они вам нужны, не все время одинаково. Потратить 2 часа на написание тестов, чтобы сэкономить 1 час, когда я нахожусь в кризисном режиме - это того стоит.
Проще писать тесты одновременно с написанием кода
Чтобы правильно написать модульные тесты, вы должны понимать код, который я тестирую. Я часто использую модульное тестирование как упражнение в понимании, но модульное тестирование существующего кода может занять много времени, потому что понимание существующего кода отнимает много времени. Сравните это с написанием тестов, когда вы пишете код, и вы найдете его гораздо быстрее, потому что вы уже понимаете код - вы просто написали его!
Определение унаследованного кода от Michael Feathers - это код без тестов. Независимо от того, согласны ли вы с его определением, ясно, что существенная часть затрат на изменение существующего кода обеспечивает его работу в соответствии с ожиданиями, часто даже неясно, каково ожидаемое поведение.
Написание модульных тестов компенсирует эту стоимость, кодируя понимание того, каково правильное поведение, а также предоставляя легкий способ «будущему нам» проверить, что поведение все еще корректно.
источник
Это хороший вопрос, и FWIW я добавлю два моих цента.
Около года назад я занимался кодированием в Salesforce, платформе, которая имела встроенный механизм, который заставлял вас не обязательно писать тесты перед написанием кода , а скорее заставлял вас писать тесты в целом.
Это работало так, что система заставляла вас писать тесты, и она вычисляла количество строк вашего кода, которые были протестированы, в процентах. Если весь код в вашем производственном экземпляре упал ниже 75% протестированных. Salesforce больше не работает.
Конечным результатом этого было то, что каждый раз, когда вы что-то делали в Salesforce, вам приходилось писать или обновлять тесты. Хотя я уверен, что это оказывает огромное влияние на долю рынка Salesforce, с точки зрения жизни разработчика, это была огромная боль в заднице .
Большую часть времени вы просто пытались получить небольшой билет, а затем приходит тестирование, которое удваивает время разработки, для функции, которая, как вы знаете, работает.
Затем неловкая концепция TDD охватила наш отдел, вплоть до наших баз данных. Наши архитекторы хотели провести тщательное тестирование во всех аспектах нашего ИТ-отдела. Легкие боли в заднице, встречаются еще большие боли в заднице.
Тогда TDD действительно никогда не имел смысла для меня, и даже сейчас это все еще не имеет. Большая часть функциональности, которую я написал в моей нынешней роли, имеет механизм, аналогичный тому, который вы упомянули: в вертикальных срезах, которые я уточняю, пока они не будут работать. Когда я был в этой старой роли, и до сих пор я часто не знаю, что собирается делать мой код, пока я на самом деле не напишу его , поэтому идею о том, что я могу писать тесты для управления кодом, я просто напишу. ... не имеет смысла для меня, это громоздко, и в основном пустая трата времени.
Все это говорит о том, что испытания - это чудесные и волшебные вещи, которые делают все правильно в мире . Они делают ваш код правильным, они гарантируют, что ваше приложение делает то, что вы думаете, и в целом все гладко. В таком случае вопрос не в том, пишете ли вы свои тесты перед тем, как писать код, или после того, как вы пишете код, вопрос в том, сколько времени вы собираетесь посвятить тестированию. Это реальная проблема, по крайней мере, в моем опыте разработки программного обеспечения. Тестирование требует времени и денег, и вы должны делать это в рамках конкурирующих интересов.
И так, в общем, я с вами согласен: TDD на практике немного неловко и громоздко. На этом этапе вы должны помнить, что работает лучше всего в вашей текущей ситуации . Если вы пишете критический код, просто убедитесь, что он проверен в целом. Если у вас есть время, попробуйте TDD и посмотрите, добавит ли он что-нибудь в процесс.
источник
Я не мог бы порекомендовать ваш подход.
Если бы я использовал ваш подход, это было бы, например, следующим образом (дом - это приложение):
Так что ваш подход стоит много времени и знаний, прежде чем я построю дом с вашим подходом. Или это займет кучу времени! Кроме того, это не очень хороший джентльмен, чтобы позволить другим писать тесты для вашего кода, когда там изменились требования.
Таким образом, есть лучший подход без программирования «прототипа» и чем начинать рефакторинг. Вместо программирования прототипа "сделайте дизайн с использованием UML вашего приложения следующим образом.
Конечно, этот подход также требует некоторых знаний в UML, но он быстр в изучении. И это всегда быстрее переименовать класс или переместить стрелки в биграмме, чем сделать это в вашей IDE. Но изучение использования тестовых фреймворков будет более утомительным в начале. Лучше всего посмотреть тестирование проектов с открытым исходным кодом и посмотреть, как они работают. Но когда вы тестируете приложение, следующее приложение будет намного быстрее. И я думаю, это хорошее чувство знать, что все работает хорошо.
Поэтому я просто отказываюсь голосовать за подходы, потому что они очень трудоемки для начинающих и, в конце концов, не очень хороши. Чтобы иметь четкие границы между вашей структурой и поведением, вы можете использовать управляемый доменом дизайн и в разделе «Организовать домен» с двумя пакетами (один пакет с именем структура, а другой с именем поведение). Также для ваших тестов. простой пример, проверьте этот пример, написанный на Java.
источник
Вы проверили вручную каждую возможную ветвь ваших условий после небольшого изменения? Сколько времени занимает петля обратной связи вашего ручного тестирования. Насколько это близко к петле обратной связи вы получаете с помощью автоматических тестов.
Автоматизированные тесты (неважно, в первую очередь тестирование или нет) заставляют вас идти быстрее - обеспечивая более быструю обратную связь с вашим кодом.
Вы уверены, что не забудете протестировать какое-то условие вручную через шесть месяцев - не говорите, что вы задокументируете все важные условия для тестирования - потому что написание вида документации / комментария равнозначно написанию теста (исполняемая документация)
И снова: во время рефакторинга вы вручную тестировали всю логику, на которую влияет рефакторинг? Сколько времени занимает проверка на изменение рефакторинга? Если рефакторинг ломает какой-то код, как долго вы находите причину перерывов?
Красивый и чистый код, который вам понравился, очень субъективен. Ваш код может быть чистым и разумным для вас. Лучший способ проверить, действительно ли ваш код читабелен, понятен и тестируем, - это тесты и обзоры кода, сделанные другими разработчиками.
Вы нашли свой путь очень продуктивным только потому, что вы только разработчик, работающий с кодом, и, я думаю, потому что вы только начинаете работать в этом проекте (Сколько лет этому проекту вы работаете? 6 - 8 месяцев?).
Вы все еще помните все, что написали, и можете распознать причину возможных проблем. Я почти уверен, что вы начнете писать тесты с начала 2-3 года вашего проекта - потому что вы хотите быть уверены, что ничего не забудете.
источник
Если вы никогда не ошибаетесь, вам не нужны тесты. Большинство разработчиков совершают ошибки, но если вы никогда этого не сделаете, и вы уверены, что никогда не сделаете ошибок в будущем (и вы единственный в проекте), то нет смысла тратить время на написание тестов.
Но ваше решение на полпути, потому что вы предлагаете писать тесты при изменении кода, но в то же время ваш метод предполагает, что вы никогда не допустите ошибок, когда решите, для каких частей кода писать тесты. Это работает, только если вы всегда прекрасно понимаете, на какие области могут повлиять изменения. Я думаю, что многие обычные разработчики (не вы, конечно!) Испытали необходимость внести изменения, и затем тест где-то неожиданно провалился, потому что вы допустили ошибку.
Конечно, хорошая архитектура, принципы SOLID и т. Д. Должны предотвращать это, но большинство разработчиков не совершенны, и именно поэтому тесты во всей системе ценны.
источник