В TDD, в чем преимущество запуска тестов, прежде чем даже писать пустой метод? - PullRequest
23 голосов
/ 06 января 2009

Я вижу много практикующих TDD, следующих за этим циклом:

1) Напишите свой тест, как если бы цель объекты и API уже существуют.

2) Скомпилируйте решение и посмотрите его перерыв.

3) Напишите достаточно кода, чтобы получить его компиляции.

4) Запустите тест и посмотрите, не удастся ли.

5) Напишите достаточно кода, чтобы получить его проходить.

6) Запустите тест и убедитесь, что он прошел

7) Рефакторинг

В чем преимущество шагов 1 и 2? С IDE, такими как Visual Studio, это действительно раздражает, так как intellisense перепрыгивает повсюду, пытаясь угадать методы и атрибуты, которых там нет.

Обычно я начинаю с шага 3, когда все мои методы выдают исключение NotImplementedException, и мне это кажется вполне подходящим, но, возможно, я что-то упускаю.

Редактировать для уточнения : это не вопрос, почему я должен увидеть, что тест не пройден до того, как он пройдет; это рассматривается на шаге 3, и это имеет смысл. Мой вопрос заключается в том, почему еще до этого люди будут вызывать метод в модульном тесте, который не существует в API (поэтому VS покажет красный загогулин, или раскрасит все имя метода красным и т. Д.) И попытается все равно скомпилировать. Для меня факт, что VS говорит мне, что метод не существует, достаточно хорош.

Ответы [ 14 ]

18 голосов
/ 06 января 2009

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

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

12 голосов
/ 06 января 2009

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

Попробуйте это как исправленную последовательность:

1) Напишите свой тест в течение комментарий , как будто целевые объекты и API уже существует.

2) Написать достаточно кода API для компилировать.

3) Раскомментируйте свой тестовый код.

4) Запустите тест и убедитесь, что он не пройден.

5) Напишите достаточно кода, чтобы получить его пройти.

6) Запустите тест и убедитесь, что он прошел

7) Сполосните и повторите ...

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

10 голосов
/ 06 января 2009

Я думаю, что всем не хватает критической точки - как вы ЗНАЕТЕ, что желаемый метод еще не существует? Написание модульного теста, который вызывает метод, который еще не должен существовать, с последующим наблюдением за его ошибкой, подтверждает, что ваше предположение верно. На скомпилированном языке он не должен компилироваться. В некомпилированном языке неудачное выполнение может быть гораздо быстрее, чем проверка API. В большинстве языков наследование и полиморфизм могут привести к появлению метода, который не был зарегистрирован в вашей ментальной модели API.

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

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

РЕДАКТИРОВАТЬ: От Джастина Стандарт ...

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

РЕДАКТИРОВАТЬ: Из Senfo ...

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

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

10 голосов
/ 06 января 2009

Рабочий процесс в Eclipse с JUnit (в отличие от Visual Studio с MSTest) - это то, где шаги 1-3 имеют наибольшее значение. Шаг 3 - это просто использование функциональности Eclipse Quick Fix (Ctrl-1) для генерации кода заглушки на основе только что написанного вами модульного теста.

DoesntExistYet someObject = new DoesntExistYet ();
int result = someObject.newMethod ("123");
assertEquals (123, результат);

Быстрое исправление для первой строки автоматически создаст класс DoesntExistYet (позволяя вам сначала пройти через мастер, чтобы настроить его), а следующее быстрое исправление создаст для вас newMethod, соответствующим образом выяснив сигнатуру в зависимости от того, как вы ее использовали. .

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

3 голосов
/ 06 января 2009

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

Если вы используете более мощные IDE для редактирования кода, например то, что у вас есть в Java (Eclipse, Netbeans, IntelliJ), первые два шага имеют больше смысла. Быстрые исправления и средства генерации кода, доступные там, делают написание теста для несуществующего класса или метода самым быстрым способом создания этого конкретного класса или объявления этого конкретного метода; Вы можете просто нажать кнопку, и недостающий класс или метод генерируется для вас. Написание вызова метода или создания объекта происходит быстрее, чем сначала создание класса или метода, а затем их использование. Например, после того, как вы вызвали метод, в качестве имени метода и типов параметров указывается, какой должна быть подпись метода, поэтому в среде IDE их легко создать. Это действительно замечательный процесс, и я бы не стал программировать по-другому. В сочетании с преимуществами фактической работы с API до его появления, описанный вами способ выполнения TDD имеет большой смысл.

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

Для пользователей Visual Studio, если вы хотите поделиться этим опытом, установите плагин Resharper для Visual Studio. Это даст многие из тех функций, которые доступны в Java IDE.

3 голосов
/ 06 января 2009

написание тестов сначала заставляет вас выбирать интерфейсы

это все.

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

РЕДАКТИРОВАТЬ: я действительно должен прочитать вопрос более внимательно, ОП искал более конкретный ответ. Вот оно: пропустите шаг 2 в Visual Studio, вместо этого заглушите методы / классы. Нет причин для педантизма в отношении следования этому расширенному рецепту, когда он явно не нужен с инструментами, которые он использует.

3 голосов
/ 06 января 2009

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

Кроме того, попытка «использовать» API заставляет задуматься об этом с другой точки зрения (с точки зрения API user ), что почти всегда полезно. Важно сделать это до того, как вы попытаетесь написать API (что всегда будет с точки зрения разработчика API ). Трудно объяснить ценность использования ваших собственных API, но отраслевой термин собачий корм .

2 голосов
/ 06 января 2009

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

1 голос
/ 11 января 2009

Насколько я понимаю, "вижу красное закорюшку" == сбой компилятора. Помните, что оригинальные манифесты модульного теста / TDD были написаны без учета IDE. Хорошие IDE в то время были очень редки в мире Java, и, как отмечали другие, динамические языки до сих пор не могут определить, что метод не существует во время компиляции.

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

1 голос
/ 07 января 2009

Это не тест-ориентированная разработка по книге . «официальный» процесс TDD , как описано в Beck «Разработка через тестирование: примером», выглядит следующим образом:

  • Быстро добавить тест
  • Запустите все тесты и увидите новый fail
  • сделать небольшое изменение
  • Запустите тесты и посмотрите их все успешно
  • Рефакторинг для удаления дубликатов
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...