Приводит ли каркас изоляции (Moq, RhinoMock и т. Д.) К чрезмерной спецификации теста? - PullRequest
2 голосов
/ 10 мая 2010

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

Итак, что, по вашему мнению, является лучшим подходом для противодействия этому?

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

2) Фавор, полностью реализованные подделки.

3) Реализуйте свои заглушки / подделки, чтобы они сделали ваш тест просто успешным, а затем разберитесь с хрупкостью, которую это может привнести.

Ответы [ 3 ]

3 голосов
/ 10 мая 2010

Я не думаю, что вы должны отдавать предпочтение ручному тестированию - если вы не предпочитаете тестировать вместо кода.

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

В двух словах: написание хрупких тестов можно выполнять с подделками или без них, и наоборот.

1 голос
/ 10 мая 2010

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

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

0 голосов
/ 10 мая 2010

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

ИМХО, есть два способа справиться с этим:

  1. Ваши тесты охватывают только публичный контракт класса - стратегию тестирования, которая широко применяется по той же причине: вам не нужно менять свои тесты, пока публичный контракт остается постоянным. К сожалению, это не то, что вы будете иметь при разработке на основе тестов.
  2. Если ваши тесты происходят из процесса TDD, то они будут регулярно охватывать закрытый код. Это означает, что они сломаются, если вы измените код. Единственный способ сохранить синхронизацию - это исправить тесты вместе с кодом. Это означает больше обслуживания во время разработки. Нет никакого рецепта, чтобы легко справиться с этим (кроме выброса теста, конечно ...).

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...