Я играю с игрушечным проектом дома для лучше понимания Теста Управляемый Дизайн. В первых вещах, казалось, подходил, и я вошел в колебание проваливания тестов, кода, пройдя тест.
Я затем приехал для добавления теста и понял, что это будет трудно с моей текущей структурой и что, кроме того, я должен разделить конкретный класс, который имел слишком много обязанностей. Добавление еще большего количества обязанностей по следующему тесту было явно неправильным. Я решил отложить этот тест и осуществить рефакторинг то, что я имел. Это - то, где вещи начали идти не так, как надо.
Было трудно осуществить рефакторинг, не повреждая много тестов сразу, и затем единственная опция, казалось, была, чтобы внести много изменений и надеяться, что я закончил назад в чем-то, куда тесты передали снова. Сами тесты были допустимы, я просто должен был повредить почти всех их при рефакторинге. Рефакторинг (которым я все еще не настолько доволен) взял меня за пять или шесть часов до того, как я возвратился ко всей тестовой передаче. Тесты действительно помогали мне по пути.
Такое чувство, что я вышел из дорожки TDD. Что Вы думаете, что я сделал неправильно?
Поскольку это - главным образом осуществление изучения, я рассматриваю откат всего этого рефакторинга и попытку продвинуться снова лучшим способом.
Возможно, вы слишком поторопились при расщеплении класса. Шаги для рефакторинга извлечения класса следующие:
Таким образом, вы не нарушите большое количество тестов при рефакторинге класса, и сможете полагаться на тесты, чтобы убедиться, что ничего не было нарушено на протяжении всего процесса разделения класса.
Также убедитесь, что вы тестируете поведение, а не реализацию.
Возможно, вы тестировали слишком низкий уровень. Трудно сказать, не видя вашего кода, но обычно я тестирую функцию от конца до конца и убеждаюсь, что все поведение, которого я ожидал, произошло. Тестирование каждого отдельного метода в изоляции даст вам тестовую паутину, которую вы создали.
Вы можете использовать такие инструменты, как NCover и DotCover, чтобы проверить, не пропустили ли вы какие-либо пути кода.
Это, к сожалению, то, о чем сторонники TDD говорят недостаточно, и что заставляет людей пробовать TDD, а затем бросать его.
Я делаю то, что я называю "тестированием высокого уровня", которое заключается в том, что я избегаю юнит-тестов и делаю исключительно тесты высокого уровня (которые мы могли бы назвать "интеграционными тестами"). Это работает довольно хорошо, и я избегаю (очень важной) проблемы, о которой вы упомянули. Я написал статью об этом некоторое время назад:
http://www.hardcoded.net/articles/high-level-testing.htm
Удачи с TDD, не сдавайтесь пока.
Единственное, что было "неправильно" - это добавление теста после этого. В "истинном" TTD вы сначала объявляете все тесты перед фактической реализацией. Я говорю "истинный", потому что часто это только теория. Но на практике у вас все еще есть безопасность, обеспечиваемая тестами.
Я хотел прокомментировать принятый ответ, но моя текущая репутация не позволяет мне. Итак, это новый ответ.
TDD говорит:
Создайте неудачный тест. Немного кодируйте. Сделайте тест пройденным.
Он настаивает на кодировании крошечными шагами (особенно в начале). Рассматривайте TDD как систематическую проверку последовательных рефакторингов, которые вы выполняете при создании своих программ. Если вы сделаете слишком большой шаг, ваш рефакторинг выйдет из-под контроля.
Также для непрерывной регрессии тестовых примеров TDD также необходима. Поэтому необходима непрерывная интеграция с инструментами покрытия (как упоминалось выше). Чтобы небольшие изменения (например, рефакторинг) можно было легко регрессировать, и можно ли было легко найти какой-либо путь кода, который был упущен.
Также я считаю, что если тесты не были написаны ранее, не следует тратить время на размышления, писать тесты или нет. Тесты надо писать сразу.