У меня в основном есть суть TDD. Я продал, что это полезно, и у меня есть разумное командование структурой MSTEST. Однако до настоящего времени я не смог перейти к использованию его в качестве основного метода разработки. В основном я использую его как суррогат для написания консольных приложений в качестве тестовых драйверов (мой традиционный подход).
Самым полезным для меня является то, как он поглощает роль регрессионного тестирования.
Я еще не построил ничего такого, что бы конкретно изолировало различные тестируемые поведения, что является еще одной важной частью картины, которую я знаю.
Таким образом, этот вопрос состоит в том, чтобы попросить указателей на то, какие первые тесты я мог бы написать для следующей задачи разработки: я хочу создать код, который инкапсулирует выполнение задачи в духе производителя / потребителя.
Я остановился и решил написать этот вопрос после того, как написал этот код (интересно, смогу ли я на самом деле использовать TDD на этот раз)
Код:
interface ITask
{
Guid TaskId { get; }
bool IsComplete { get; }
bool IsFailed { get; }
bool IsRunning { get; }
}
interface ITaskContainer
{
Guid AddTask(ICommand action);
}
interface ICommand
{
string CommandName { get; }
Dictionary<string, object> Parameters { get; }
void Execute();
}
Ответы:
Начиная с этой концепции:
1) Начните с поведения, которое вы желаете. Напишите тест для этого. Смотри тест провалился.
2) Напишите достаточно кода, чтобы пройти тест. Смотреть все тесты проходят.
3) Ищите избыточный / неаккуратный код -> рефакторинг. Смотрите тесты еще пройти. Перейти к 1
Итак, в # 1, скажем, вы хотите создать новую команду (я перехожу к тому, как команда будет работать, так что терпите меня). (Кроме того, я буду немного прагматичным, а не экстремальным TDD)
Новая команда называется MakeMyLunch, поэтому вы сначала создаете тест для ее создания и получаете имя команды:
Это терпит неудачу, вынуждая вас создать новый класс команд и заставить его вернуть его имя (пурист сказал бы, что это два раунда TDD, а не 1). Таким образом, вы создаете класс и реализуете его интерфейс ICommand, включая возвращение имени команды. Запуск всех тестов теперь показывает все прохождения, поэтому вы продолжаете искать возможности рефакторинга. Наверное, нет.
Итак, затем вы хотите, чтобы он реализовал execute. Поэтому вы должны спросить: откуда мне знать, что «MakeMyLunch» успешно «сделал мой обед». Какие изменения в системе из-за этой операции? Могу ли я проверить это?
Предположим, что это легко проверить на:
В других случаях это сложнее, и вы действительно хотите проверить обязанности испытуемого (MakeMyLunchCommand). Возможно, ответственность MakeMyLunchCommand заключается во взаимодействии с холодильником и микроволновой печью. Таким образом, чтобы проверить это, вы можете использовать макет Холодильник и макет Микроволновая печь. [два примера макетов фреймворка - Mockito и nMock или посмотрите здесь .]
В этом случае вы должны сделать что-то вроде следующего псевдокода:
Пурист говорит: проверь ответственность своего класса - его взаимодействия с другими классами (открыла ли команда холодильник и включила ли микроволновая печь?).
Прагматик говорит, что тест для группы классов и тест на результат (ваш обед готов?).
Найдите правильный баланс, который работает для вашей системы.
(Примечание: учтите, что, возможно, вы пришли к своей структуре интерфейса слишком рано. Возможно, вы сможете позволить этому развиваться по мере написания своих модульных тестов и реализаций, и на шаге 3 вы «заметите» общую возможность интерфейса).
источник