2013-04-26 2 views
0

В моем недавнем проекте члены моей команды и я собрались, выполнили требования и создали интерфейсы (с объявлениями методов, но не с реализациями), которые мы все согласовали. Затем мы начали писать модульные тесты, а затем реализацию.Тестирование единиц. До или после создания интерфейса?

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

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

Какой правильный подход?

ответ

1

Испытательная разработка начинается с модульного испытания.

В ваших модульных тестах вы определяете фазы дерева: Упорядочить, действовать и утверждать. В настоящий момент ваш код не будет компилироваться, потому что классы/интерфейсы еще не определены.

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

Написав модульные тесты в первую очередь, вы заставляете себя смотреть за пределами своих классов, прежде чем думать об осуществлении. Это способ сделать TDD.

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

+0

Спасибо, вы прояснили некоторые вещи, которые я не понял полностью. – Swyish

0

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

+0

Благодарим за отзыв. – Swyish

2

Более TDD

Start над TDD, и думаю, что с точки зрения истории, или случаи использования, а также требования, которые они имеют. Определите требования в терминах теста. Скажите, что вы работаете на веб-сайте, продающем носки. История может быть прочитана: как клиент, мне нужно ввести количество предметов, которые я покупаю, чтобы получить скидки на пакет. Таким образом, вы создаете тест, в котором говорится, что «клиент ввел 24 пары носков, чтобы в заказе была добавлена ​​скидка 5%». Но это действительно высокий уровень. Вы смотрите на код и говорите «эй, я даже не поддерживаю количество». Итак, вы думаете о позициях в вашем заказе и о том, как им нужно иметь количество. Вы пишете тест для своего объекта LineItem, который говорит

LineItemTest::testAddQuantity() 
{ 
    LineItem lineItem = new LineItem(); 
    Item item = new Item(); 
    lineItem.add(item); 
    lineItem.addQuantity(7); 
    ASSERT(lineItem.getQuantity() == 7); 
} 

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

LineItemTest::testExtendPrice() 
{ 
    LineItem lineItem = new LineItem(); 
    Currency price = 1.00; 
    Item item = new Item(price); 
    lineItem.add(item); 
    lineItem.addQuantity(7); 
    ASSERT(lineItem.getExtendedPrice() == 7.00); 
} 

Таким образом, мы изменили интерфейс на LineItem, указав новое требование.

Самый важный урок состоит в том, что если бы мы не думали о ExtendedPrice при разработке интерфейса LineItem, мы бы застряли здесь, потому что наши требования отчаянно требуют одного. С TDD вам не нужно было разрабатывать его заранее, потому что независимо от того, что вы думали во время дизайна, вам все равно понадобилось бы, когда вы все равно сюда попали.

Emergent Design

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

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

В это время вы также разрешаете вводить все «что делать». Что делать, если мы вводим отрицательное количество? Добавьте еще один тест!

Экономия времени

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

Модульное тестирование позволяет использовать эту гибкость. С модульными тестами вы можете что-то изменить и повторно запустить тесты бесплатно, уверенные в том, что ваши изменения ничего не изменили.

Проблемы избежать

A Big Design Up Front не защищает вас. Напротив, это может помешать вам делать правильные вещи в нужное время. Я видел, как команды застряли в большом дизайне, полностью забыв о некоторых деталях, и вместо того, чтобы устанавливать дизайн, чтобы добавить детали, они исправляют недостатки. «Мой проект отстает от графика, мы не можем изменить дизайн сейчас, мы просто сделаем обходной путь». Вот откуда исходит код спагетти, и чаще всего это ошибка процесса, приводящего к неправильным решениям.

Внешние зависимости

Часто, несмотря на то, что вы создаете внутри, вы все еще имеет дело с внешним миром. Службы, фиксированные требования, устаревшая схема базы данных, все это проблемы реального мира, с которыми вам приходится иметь дело в TDD. Итак, если у вас есть внешний интерфейс для другой системы, как вы к этому подходите? Как и любое другое требование: с тестом.

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

+0

Спасибо, я наконец-то нашел время, чтобы прочитать все это :). Была большая помощь. – Swyish

+0

Согласовано. «Big Design Up Front» действительно приводит к ошибкам бездействия. Но, возможно, больше беспокоит то, что это также приводит к ошибкам избыточного включения. Элементы разрабатываются, потому что вы считаете, что вам понадобятся они для той или иной функции, но, оказывается, вы этого не делаете. Эти элементы теряют время, как правило, только частично реализованы и плохо протестированы. –

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