TDD: “Протестируйте только” методы

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

Мы используем BDD/TDD sytle методология для создания нашего программного обеспечения (вполне большое / сложное приложение), конечный результат.. поведенческие спецификации (Стиль Given/When/Then) полученный из бизнес-требований, модульные тесты, которые отражают их и код, который отражает требования тестов.

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

Проблема, некоторые Репозитории Объекта не имеют, удаляют методы, поскольку еще не было никакого бизнес-требования, выраженного для них. Многие имеют, Архивируют/Восстанавливают/копируют и т.д. (и может иметь, удаляют ожидание на отставании).

Таким образом, теперь у нас есть тестовое требование отдела для удаления (но тот, который конфликтует с историями бизнес-пользователя),

Так.... Мой вопрос состоит... в том, если я должен был добавить методы специально для испытательного цеха... what't лучший способ обработать их. Я понимаю, что это обычно считают плохой практикой в "Утопии TDD", но реалистично, как Вы имели дело с этим видом конфликта?

Первые мысли, которые я имел, являются любой именованием использования...

void TestOnly_Delete(Guid id){} 

... атрибуты...

[TestOnly]
void Delete(Guid id){}

... или директивы компилятора...

#if TESTBUILD
void Delete(Guid id){}
#endif

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

... или просто обманите и добавьте пользовательскую историю для управления им тот путь;-)

Опыт или совет с благодарностью ценятся?

Заранее спасибо.

14
задан ChrisV 19 February 2010 в 11:41
поделиться

5 ответов

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

Если это правда, то непременно просто добавьте , если вы можете сделать это легко .

Однако иногда бывает и обратное. В этом случае вы должны сопротивляться желанию добавить участника. Однако часто вы можете следовать Принципу открытости / закрытости и открыть свой API, чтобы другие могли добавить желаемую функциональность. Тестируемость - это просто другое слово для принципа открытости / закрытости .

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

4
ответ дан 1 December 2019 в 16:31
поделиться

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

1
ответ дан 1 December 2019 в 16:31
поделиться

Обычно я получаю проект / библиотеку «только для тестирования», в которых хранятся все макеты / вспомогательные классы, которые мне нужны для моих тестов. Добавление необходимых классов / методов в эту фиктивную библиотеку, которая не включена в производственный код, кажется естественным соответствием этому требованию. Если у вас еще нет такой библиотеки и вы не хотите ее создавать, я бы отметил - если возможно - внутренние методы и предоставил бы их только среде тестирования. Вы не указываете платформу, но я знаю, что это возможно с C # /. NET, и я часто использую эту возможность, чтобы предоставить своим тестам доступ к методам, которые в противном случае были бы недоступны за пределами библиотеки.

С другой стороны, я бы сказал, что тестировщики являются такой же частью вашего анализа требований, как и фактические клиенты. Точно так же, как у нас есть некоторые требования, которые предназначены исключительно для наших нужд разработки, у нас также есть некоторые требования для тестирования. Уловка, как вы обнаружите, состоит в том, чтобы разработать код таким образом, чтобы все потребности заинтересованных сторон были удовлетворены в максимально возможной степени. Когда потребности конфликтуют, мы стараемся найти наилучший возможный компромисс. ИМО, возможность удаления из библиотек, предназначенных только для тестирования, является разумным компромиссом с потребностью клиента в безопасности данных (без удаления).

1
ответ дан 1 December 2019 в 16:31
поделиться

Я никогда не буду добавлять в свой код методы удаления или другие методы очистки только для поддержки автоматического тестирования.

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

0
ответ дан 1 December 2019 в 16:31
поделиться

Это интересный вопрос. У меня есть некоторые мысли, но я не уверен, что это станет ответом на вашу проблему.

Я лично создам явный набор интерфейсов, унаследованных от того, что у вас уже есть для объекта, такого как IIntTest_Customer: ICustomer, и определю там метод удаления. Если возможно, попытайтесь поместить все эти интерфейсы в отдельный проект, чтобы разработчик даже не имел ссылки на него из обычного проекта и избегал их случайного использования. Затем отдел тестирования будет использовать этот конкретный внутренний тестовый интерфейс для своих целей тестирования.

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

0
ответ дан 1 December 2019 в 16:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: