TDD: С чего начать первый тест

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

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

Я чувствую, что готов начать писать программу, и я решил заставить себя, наконец, сделать TDD от начала до конца.

Но теперь я понятия не имею, с чего начать. (Я также задаюсь вопросом, не обманываю ли я процесс TDD, уже имею представление о потоке программы для пользователя.)

Пользовательский поток действительно серийный и представляет собой всего лишь несколько шагов. В качестве примера первым шагом будет:

  • пользователь отправляет номер производственного заказа и получает список сериализуемых номеров деталей этого заказаного материала.

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

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

// This isn't what I'd want my code to end up looking like
// but it is the simplest statement of what I want
IList<string> partNumbers = GetPartNumbersForMfgOrder(string mfgOrder);

Прочитав примерную книгу Кента Беккса, он рассказывает о выборе небольших тестов. Это похоже на довольно большой черный ящик. Это потребует репозитория mfg order, и я должен сканировать дерево структуры продукта, чтобы найти все применимые номера деталей для этого заказа mfg, и я даже не определил свою модель домена в коде вообще.

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


В качестве побочного примечания... это как использовать истории?

Как ассемблер Я хочу получить список номеров деталей по заказу mfg Чтобы я мог выбрать, какой из них будет сериализован

Чтобы быть правдивым, ассемблер никогда не говорил об этом. Все, что хочет ассемблер, это завершить операцию по порядку mfg:

Как ассемблер Я хочу отметить детали серийным номером Чтобы закончить операцию по порядку mfg

Ответы

Ответ 1

Вот как бы я начал. Предположим, у вас нет абсолютно никакого кода для этого приложения.

  • Определите историю пользователя и бизнес-ценность, которую он приносит: "В качестве пользователя я хочу отправить номер производственного заказа и список номеров деталей этих заказов, чтобы я мог отправить список в систему инвентаризации"
  • начните с пользовательского интерфейса. Создайте очень простую страницу (предположим, что ее веб-приложение) с тремя полями: ярлыком, списком и кнопкой. Это достаточно хорошо, не так ли? Пользователь мог скопировать список и отправить в систему inv.
  • Используйте шаблон, чтобы настроить свой desig, например MVC.
  • Определите тест для вашего метода контроллера, который вызывается из пользовательского интерфейса. Вы тестируете здесь, что контроллер работает, а не то, что данные верны: Assert.AreSame(3, controller.RetrieveParts(mfgOrder).Count)
  • Напишите простую реализацию контроллера, чтобы убедиться, что что-то возвращается: return new List<MfgOrder>{new MfgOrder(), new MfgOrder(), new MfgOrder()}; Например, вам также необходимо реализовать классы для MfgOrder.
  • Теперь ваш пользовательский интерфейс работает! Работает некорректно, но работает. Поэтому давайте ожидать, что контроллер получит данные от службы или DAO. Создайте объект Mock DAO в тестовом примере и добавьте ожидание того, что вызывается метод "partsDao.GetPartsInMfgOrder()".
  • Создайте класс DAO с помощью метода. Вызовите метод из контроллера. Теперь ваш контроллер выполнен.
  • Создайте отдельный тест для тестирования DAO, наконец, убедившись, что он возвращает правильные данные из БД.
  • Продолжайте повторять, пока не получите все это. Через некоторое время вы привыкнете к этому.

Главное здесь - отделить приложение в очень малых частях и проверить эти мелкие детали по отдельности.

Ответ 2

Это нормально в качестве стартового теста. При этом вы определяете ожидаемое поведение - как оно должно работать. Теперь, если вы чувствуете, что у вас гораздо больший укус, чем вам хотелось бы.. вы можете временно проигнорировать этот тест и написать более подробный тест, который выберет часть или по крайней мере на середине. Затем другие тесты, которые ведут вас к цели сделать первый большой проход теста. Red-Green-Refactor на каждом шаге.

Небольшие тесты, я думаю, означают, что вы не должны тестировать много вещей в одном тесте. например Являются ли компоненты D.A, B и C в состоянии 1, состоянии2 и состоянии3 после того, как я вызвал Method1(), Method2() и Method3() с этими параметрами на D. Каждый тест должен проверять только одно. Вы можете искать SO для качественных тестов. Но я бы счел ваш тест небольшим тестом, потому что он короткий и сосредоточен на одной задаче - "Получение PartNumbers From Manufacturing Order"

Обновить. В качестве предложения To-Try (AFAIR из книги Бек) вы можете сесть и составить список однострочных тестов для SUT на листе бумаги. Теперь вы можете выбрать самые простые (тесты, которые вы уверены, что сможете сделать.), Чтобы создать определенную уверенность. ИЛИ вы можете попробовать тот, у которого вы на 80% уверены, но имеет некоторые серые области (мой выбор тоже), потому что это поможет вам узнать что-то о SUT на этом пути. Держите те, о которых вы не знаете, как действовать в конце... надеюсь, что к тому времени, когда будут сделаны более простые, будет яснее. Ударьте их один за другим, когда и когда они станут зелеными.

Ответ 3

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

Вот история, которая может потребовать немного разрушения:

  • В качестве пользователя я хочу отправить номер производственного заказа и получить список сериализуемых номеров деталей этого материала для заказов.

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

Ответ 4

Хорошо, вы попали в ту же самую стену, что и я, когда впервые пробовали TDD:)

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

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

Су, по моему опыту (не в опыте какого-то автора, который пользуется сопоставлением аналогов реального мира с OO: P), TDD должен выглядеть следующим образом:

  • Создайте диаграмму развертывания, из спецификации требования (ofc, ничто не установлено в камне - когда-либо)
  • Выберите историю пользователей для реализации
  • Создайте или измените модель своего домена, чтобы включить эту историю.
  • Создайте или измените свою диаграмму классов, чтобы включить эту историю (включая различные классы дизайна).
  • Идентифицировать тестовые векторы.
  • Создайте тесты на основе интерфейса, который вы сделали на шаге 4
  • Проверьте тесты (!). Это очень важный шаг.
  • Реализация классов
  • Проверить классы
  • Иди, пиво со своими коллегами:)