Экстремальное программирование. Разработка через тестирование | страница 81
Если вы с самого начала приступите к реализации реалистичного теста, вам придется искать ответы на несколько вопросов одновременно:
• Где должна располагаться операция?
• Какие входные данные считать корректными?
• Каким должен быть корректный результат выполнения операции при использовании выбранных входных данных?
Если вы начнете с реалистичного теста, вы слишком долгое время будете вынуждены действовать без обратной связи. Красный – зеленый – рефакторинг, красный – зеленый – рефакторинг. На выполнение этого цикла должно уходить всего несколько минут.
Но как сократить время цикла? Для этого вы можете воспользоваться тривиальными входными и выходными данными. Вот простой пример: если функция должна складывать многозначные вещественные числа с точностью до тысячного знака после запятой, вовсе не обязательно начинать ее реализацию с теста, проверяющего результат сложения таких огромных чисел. Вполне можно начать с тривиального теста 3 + 4 = 7. Вот еще один пример. В группе электронных новостей, посвященной экстремальному программированию, один из участников поинтересовался, как написать программу минимизации количества полигонов (многоугольников), составляющих некоторую поверхность. На вход подается набор полигонов, комбинация которых представляет собой некоторый трехмерный объект. На выходе должна получиться комбинация полигонов, которая описывает точно такой же объект (поверхность), но включает в себя минимальное возможное количество полигонов. «Как я могу разработать подобную программу, если для того, чтобы заставить тест сработать, я должен быть как минимум доктором наук?»
Используя шаблон «Начальный тест» (Starter Test), мы получаем ответ:
• Вывод должен быть точно таким же, как ввод. Некоторые комбинации полигонов изначально являются минимальными.
• Ввод должен быть как можно меньшего размера. Например, единственный полигон или даже пустой список полигонов.
Мой начальный тест выглядел следующим образом:
Reducer r = new Reducer(new Polygon());
assertEquals(0, reducer.result(). npoints);
Отлично! Первый тест заработал. Теперь можно перейти к остальным тестам в списке…
К начальному тесту следует применить рассмотренное ранее правило «Тест одного шага» (One Step Test): самый первый тест должен научить вас чему-то новому, кроме того, вы должны обладать возможностью достаточно быстро заставить его работать. Если вы реализуете подобный код уже не в первый раз, вы можете выбрать начальный тест для одной или даже двух операций. Вы должны быть уверены, что сможете быстро заставить тест работать. Если вы приступаете к реализации чего-либо достаточно сложного и делаете это впервые, начните с самого простого теста, который вы только можете представить.