2009-06-19 4 views
10

Я пытаюсь практиковать TDD.Обнаружение других объектов во время выполнения TDD

Мое понимание что TDD должен идти как этот

  1. Написать список тестов для интерфейса/класса я собираюсь развиваться.
  2. Начните с самого простого не реализованного теста из моего тестового списка.
  3. Напишите тест, еще нет кода реализации.
  4. Напишите интерфейс класса, чтобы скомпилировать код.
  5. Запустите тест, в результате чего произошел один неудачный тест.
  6. Напишите реализацию, сделав тестовый проход.
  7. Реорганизовать беспорядок, который я создал.
  8. Goto 2.

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

Что должно сделать настоящий TDD'r в этой точке?

  1. Оставить существующий список тестов в покое на некоторое время и создать новую для недавно открытого класса (та же проблема может проявляться при осуществлении нового класса Offcourse)
  2. Перейти взаимодействия На основе образом тестирования и Mock нового класса, продолжайте с тестовыми тестами класса, над которым вы работаете, и вернитесь позже, чтобы создать правильную реализацию издеваемого класса.
  3. Эта ситуация не должна присутствовать. Я, наверное, не очень хорошо продумал свой первоначальный дизайн. (но разве это не победит одну из целей TDD ?!).

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

ответ

9

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

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

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

EDIT: (В ответ на комментарий). Должен ли новый класс пройти тестирование самостоятельно? Не обязательно.Это зависит от того, развивает ли класс свое значение. Когда вы тестируете устройство, вы тестируете функциональность. Это не интеграционный тест только потому, что есть два класса. Это становится интеграционным тестом, когда две единицы начинают взаимодействовать. Граница, о которой я обычно думаю, заключается в том, что мне нужно настроить значительное состояние в группе классов A для взаимодействия с группой классов B, и особенно если группа классов A вызывает группу классов B и что Я заинтересован в тестировании, как B реагировал на A, тогда я смотрю на интеграционный тест.

+1

Но новый класс должен пройти проверку самостоятельно, не так ли? Если дизайн приводит вас в точку, где вам нравится создавать несколько классов «поддержки», начальный тест модуля становится интеграционным тестом. –

1

Вы должны создать класс-макет. Один интерфейс с предсказуемыми повторами. Таким образом, вы можете протестировать оригинал.

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

+1

На самом деле это то, что я думаю, что я должен делать, но там, там идет священная война о «основанном на состоянии» и «тестировании на основе взаимодействия». Мне не нравится тот факт, что это решение связывает ваши тесты с конкретным объявлением интерфейса, который вы используете. При тестировании на уровне штата я могу изменить объявление интерфейса поддерживающего класса (скорее всего), не меняя свои тестовые файлы. Используя тестирование на основе взаимодействия, я также должен изменить тестовые файлы. –

2

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

+0

Это то, что я делаю сейчас, но мне не нравится тот факт, что он отвлекает вас от класса, который вы тестировали. Через некоторое время вы возвращаетесь к этому классу и пытаетесь выяснить, откуда вы. –

+1

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

6

У меня есть проблема в том, что, когда я прибыть в пункт 6 & 7, в какой-то момент времени я неизменно приходят к выводу, что реализация I просто написал должны быть делегированы другого класса.

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

Но это вас беспокоит. Так что делать? Признать, что делегирование другому классу является рефакторингом; это что-то нужно сделать после шаг 6, во время шага 7. Как только вы будете зелеными, рефакторинг к лучшему дизайну. У вас уже есть тесты для нового класса; они просто подключены для вызова первоначального класса. Это прекрасно. После извлечения класса и делегирования, если вам было бы более удобно, если бы тесты вызывали извлеченный класс напрямую: пойдите для него. Никакого вреда. Если извлеченный класс начинает использоваться другими абонентами, я бы порекомендовал его, и, может быть, когда вы начнете называть его из других классов, это хорошее время для этого (но если он сейчас васчет, сделайте это сейчас).

+0

Очень прагматичный, спасибо. –

Смежные вопросы