Оценить:
 Рейтинг: 4.67

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

Год написания книги
2003
Теги
<< 1 2 3 4 5 6 >>
На страницу:
3 из 6
Настройки чтения
Размер шрифта
Высота строк
Поля
Часть I

На примере денег

Мы займемся реализацией примера, разрабатывая код полностью на основе тестирования (кроме случаев, когда в учебных целях будут допускаться преднамеренные ошибки). Моя цель – дать вам почувствовать ритм разработки через тестирование (TDD). Кратко можно сказать, что TDD заключается в следующем:

• Быстро создать новый тест.

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

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

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

• Провести рефакторинг для устранения дублирования.

Кроме того, придется найти ответы на следующие вопросы:

• Как добиться того, чтобы каждый тест охватывал небольшое приращение функциональности?

• Как и за счет каких небольших и, наверное, неуклюжих изменений обеспечить успешное прохождение новых тестов?

• Как часто следует запускать тесты?

• Из какого количества микроскопических шагов должен состоять рефакторинг?

1. Мультивалютные деньги

Вначале мы рассмотрим объект, созданный Уордом для системы WyCash, – мультивалютные деньги (см. «Введение»). Допустим, у нас есть отчет вроде этого.

Добавив различные валюты, получим мультивалютный отчет.

Также необходимо указать курсы обмена.

$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10

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

• выполнять сложение величин в двух различных валютах и конвертировать результат с учетом указанного курса обмена;

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

Составим список задач, который будет напоминать нам о планах, не даст запутаться и покажет, когда все будет готово. В начале работы над задачей выделим ее жирным шрифтом, вот так. Закончив работу над ней – вычеркнем, вот так. Когда придет мысль написать новый тест, добавим новую задачу в наш список.

Как видно из нашего списка задач, сначала мы займемся умножением. Итак, какой объект понадобится нам в первую очередь? Вопрос с подвохом. Мы начнем не с объектов, а с тестов. (Мне приходится постоянно напоминать себе об этом, поэтому я просто притворюсь, что вы так же забывчивы, как и я.)

Попробуем снова. Итак, какой тест нужен нам в первую очередь? Если исходить из списка задач, первый тест представляется довольно сложным. Попробуем начать с малого – умножение, – сложно ли его реализовать? Займемся им для начала.

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

Простой пример умножения[4 - Название метода times() можно перевести на русский как «умножить на». – Примеч. пер.]:

public void testMultiplication() {

Dollar five = new Dollar(5);

five.times(2);

assertEquals(10, five.amount);

}

(Знаю, знаю: публичные поля, побочные эффекты, целые числа для денежных величин и все такое. Маленькие шаги – помните? Мы отметим, что где-то есть душок[5 - Код с душком (code that smells) – распространенная в XP метафора, означающая плохой код (содержащий дублирование). – Примеч. пер.], и продолжим дальше. У нас есть тест, который не выполняется, и мы хотим как можно скорее увидеть зеленую полоску[6 - Имеется в виду индикатор успешного выполнения тестов в среде JUnit, имеющий форму полосы. Если все тесты выполнились успешно, полоса становится зеленой. Если хотя бы один тест потерпел неудачу, полоса становится красной. – Примеч. пер.].)

$5 + 1 °CHF = $10, если курс обмена 2:1

$5 * 2 = $10

Сделать переменную amount закрытым членом класса

Побочные эффекты в классе Dollar?

Округление денежных величин?

Тест, который мы только что создали, даже не компилируется, но это легко исправить. (О том, когда и как создаются тесты, я расскажу позже – когда мы будем подробнее говорить о среде тестирования, JUnit.) Как проще всего заставить тест компилироваться (пусть он пока и будет терпеть неудачу)? У нас четыре ошибки компиляции:

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

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

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

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

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

Dollar

class Dollar

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

Dollar

Dollar(int amount) {

}

<< 1 2 3 4 5 6 >>
На страницу:
3 из 6