Экстремальное программирование. Разработка через тестирование. Кент Бек

Читать онлайн.



Скачать книгу

У нас четыре ошибки компиляции:

      • нет класса Dollar;

      • нет конструктора;

      • нет метода times(int);

      • нет поля (переменной) amount.

      Устраним их одну за другой. (Я всегда ищу некоторую численную меру прогресса.) От одной ошибки мы избавимся, определив класс Dollar:

      Dollar

      class Dollar

      Одной ошибкой меньше, осталось еще три. Теперь нам понадобится конструктор, причем совершенно необязательно, чтобы он что-то делал – лишь бы компилировался.

      Dollar

      Dollar(int amount) {

      }

      Осталось две ошибки. Необходимо создать заготовку метода times(). Снова мы выполним минимум работы, только чтобы заставить тест компилироваться:

      Dollar

      void times(int multiplier) {

      }

      Теперь осталась только одна ошибка. Чтобы от нее избавиться, нужно создать поле (переменную) amount:

      Dollar

      int amount;

      Отлично! Теперь можно запустить тест и убедиться, что он не выполняется: ситуация продемонстрирована на рис. 1.1.

      Загорается зловещий красный индикатор. Фреймворк тестирования (JUnit в нашем случае) выполнил небольшой фрагмент кода, с которого мы начали, и выяснил, что вместо ожидаемого результата «10» получился «0». Ужасно…

      Рис. 1.1. Прогресс! Тест терпит неудачу

      Вовсе нет! Неудача – это тоже прогресс. Теперь у нас есть конкретная мера неудачи. Это лучше, чем просто догадываться, что у нас что-то не так. Наша задача «реализовать мультивалютность» превратилась в «заставить работать этот тест, а потом заставить работать все остальные тесты». Так намного проще и намного меньше поводов для страха. Мы заставим этот тест работать.

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

      Наименьшее изменение, которое заставит тест успешно выполняться, представляется мне таким:

      Dollar

      int amount = 10;

      Рисунок 1.2 показывает результат повторного запуска теста. Теперь мы видим ту самую зеленую полоску, воспетую в поэмах и прославленную в веках.

      Вот оно, счастье! Но радоваться рано, ведь цикл еще не завершен. Уж слишком мал набор входных данных, которые заставят такую странно попахивающую и наивную реализацию работать правильно. Перед тем как двигаться дальше, немного поразмышляем.

      Рис. 1.2. Тест успешно выполняется

      Вспомним, полный цикл TDD состоит из следующих этапов:

      1. Добавить небольшой тест.

      2. Запустить все тесты и убедиться, что новый тест терпит неудачу.

      3. Внести небольшое изменение.

      4. Снова запустить тесты и убедиться, что все они успешно выполняются.

      5. Устранить дублирование с помощью рефакторинга.

      ЗАВИСИМОСТЬ И ДУБЛИРОВАНИЕ

      Стив Фримен (Steve Freeman) указал, что проблема с тестами и кодом заключается не в дублировании (на которое я еще не указал вам, но сделаю это, как только закончится отступление). Проблема заключается в зависимости между кодом и тестами – вы не можете изменить