Как провести рефакторинг и выявить зависимости при выполнении BDD

Выполнение BDD означает движение сверху вниз, поэтому сначала мы пишем тест для функции верхнего уровня. Теперь, чтобы настроить тест, вам обычно нужно настроить несколько mocks вместо реальных deps. Как узнать, какие иждивенцы необходимы, какие услуги вам нужны? Я не могу придумать, как определять зависимости на этом уровне. В классической TDD снизу вверх это было так же просто, как преобразовать существующий имплант в зависимые объекты.

Означает ли BDD и mocking, что от нас требуется заранее составить полный граф зависимостей и примерно спроектировать его?

А как насчет рефакторинга? Кажется, что больше нет места для разбиения имплемента на зависимости, поскольку они у вас уже определены.

Например, мне нужно реализовать функцию кеширования по времени. Мои тесты должны быть:

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

Означает ли это, что мне нужно определить все мои потенциальные зависимости и подготовить макеты? И должен ли я проверять значения, возвращаемые моим xall, или просто ожидаемые вызовы зависимостей?


person veilsoen    schedule 29.10.2011    source источник
comment
Здесь BDD означает разработку, основанную на поведении, а не диаграмму двоичных решений. (Чтобы прояснить, почему я отменил переименование тега agf.)   -  person adl    schedule 11.11.2011


Ответы (3)


У меня такое чувство, что вы, возможно, немного над этим задумались. Когда что-то кажется действительно запутанным, я обычно напоминаю себе сделать шаг назад и пересмотреть основы. Во-первых, я хочу делать только минимум, необходимый для удовлетворения требований. Мне все равно, будет ли в системе много зависимостей, о которых я еще не знаю, поэтому я пишу свои тесты как можно проще. Если я вижу необходимость в зависимости, я добавляю имитацию и поддерживаю минимальный интерфейс, необходимый для запуска моего теста. Если в дальнейшем системе потребуется расширить или поддержать дополнительную зависимость, я могу расширить макет или даже заменить его чем-то особенным для следующего теста, который я пишу. Я мог бы также продлить тест или даже написать новый тест, чтобы удовлетворить новые требования, когда они станут мне известны и / или ясны.

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

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

Иногда у меня возникает желание создать огромное количество имитаций, чтобы справиться со всеми возможными непредвиденными обстоятельствами зависимости, которые я могу придумать, и каждый раз я возвращаюсь к повторению «KISS», «YAGNI» и «Сделайте так, чтобы это работало, тогда заставить его работать лучше ", снова и снова в моей голове, пока я не получаю сообщение, что я действительно не могу позволить себе застрять, потому что я пытаюсь думать слишком далеко вперед.

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

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

person S.Robins    schedule 30.10.2011

С BDD вы не работаете на уровне единицы (то есть с одним общедоступным методом одного общедоступного класса). Вы работаете на системном уровне. Поэтому вы захотите имитировать все, что находится за пределами системы. Это означает, что система хранения или внешняя система будут имитированы: файлы, базы данных, сервисы и т. Д.

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

Что касается того, как их обнаружить, я вижу две возможности, обе из которых вы можете использовать. Сначала нужно нарисовать системную диаграмму, которая представляет собой прямоугольник, представляющий все в вашей SUT < / сильный>. Затем нарисуйте все, что вам может понадобиться, что попадает в одну из вышеперечисленных категорий. Это то, над чем нужно издеваться.

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

Надеюсь это поможет.

person Assaf Stone    schedule 30.10.2011

Не гоните дизайн с верхнего уровня (интеграция?) - тест.

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

Коротко, но я надеюсь, вы понимаете, о чем я.

person Marcus Hammarberg    schedule 30.10.2011