Пытаясь обрести уверенность в преимуществах TDD - PullRequest
11 голосов
/ 18 июля 2010

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

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

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

1. TDD для уменьшения ошибок

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

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

...

TDD - надежный способ проектирования программные компоненты («единицы») в интерактивном режиме, чтобы их поведение уточняется через юнит-тесты. Вот и все!

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

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

2. TDD как дизайнерская парадигма

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

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

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

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

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

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

3. TDD как документация

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

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

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

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

4. TDD для регрессионного тестирования

В этом посте упоминается, что TDD не слишком полезен для выявления регрессий. Это, конечно, потому что неочевидные крайние случаи - это те, которые всегда портятся, когда вы изменяете некоторый код.

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

Ответы [ 6 ]

5 голосов
/ 18 июля 2010

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

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

Кроме того, вы пишете: «Так что, не будет ли больше смыслаписать модульные тесты по мере необходимости, всякий раз, когда код изменяется, сохраняя старый код и сравнивая его результаты с новыми функциями? "Код, который написан без учета модульного тестирования, часто не поддается тестированию, особенно если он взаимодействует с внешними сервисами, такими как база данных, менеджер транзакций, инструментарий GUI или веб-сервис.Добавление их позже просто не произойдет.

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

3 голосов
/ 18 июля 2010

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

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

2 голосов
/ 18 июля 2010

TDD - это не методология, это образ мышления.

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

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

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

1 голос
/ 07 марта 2011

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

По крайней мере, это лучше, чем ударять по F5 и использовать console.log() или даже оповещения.

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

Если вы напишете следующий jQuery, юнит-тесты станут вашими друзьями!:)

Да, и давайте не будем забывать о замечательных инструментах для js, таких как JSTestDriver !

1 голос
/ 18 июля 2010

Я просто хотел выделить:
Тесты TDD не являются модульными тестами

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

из очень хорошего сообщения в блоге Стивена Уолтера Тесты TDD не являются юнит-тестами

0 голосов
/ 18 июля 2010

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

...