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


Остальные тесты пишутся только на стороне сервера: «Предположим, что мы получаем строки наподобие этой…»

Объясняющий тест (Explanation Test)

Как распространить в своей команде использование автоматического тестирования? Для любых объяснений используйте тесты и спрашивайте тесты у тех, кто пытается вам что-либо объяснить.

Если вы единственный член команды, работающий в стиле TDD, вы можете почувствовать себя неуютно и одиноко. Однако вскоре после того, как вы начнете работать в стиле TDD, вы обратите внимание на уменьшение количества проблем, связанных с интеграцией, и снижение количества дефектов, обнаруженных в проверенном коде. Дизайн вашего кода будет проще, и его легче будет объяснять. Может случиться так, что ваши коллеги проявят интерес к тестированию и предварительному тестированию разрабатываемого кода.

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

Но что можно сделать? Лучше всего предлагать вашим коллегам объяснять работу кода в форме тестов: «Подожди-ка, если я правильно понял, объект Foo будет таким, а объект Bar будет таким, значит, в результате получится 76?» Кроме того, вы можете объяснять работу кода в виде тестов: «Вот как это работает. Если объект Foo будет таким, а объект Bar будет таким, в результате получится 76. Однако если объект Foo будет таким, а объект Bar будет таким, в результате получится 67».

Вы можете делать это на более высоком уровне абстракции. Если кто-то пытается объяснить вам работу кода при помощи диаграммы последовательности обмена сообщениями, вы можете предложить ему преобразовать эту диаграмму в более понятную форму. После этого вы пишете тест, содержащий в себе все видимые на диаграмме объекты и сообщения.

Тест для изучения (Learning Test)[15]

Когда необходимо писать тесты для программного обеспечения, разработанного сторонними разработчиками? Перед тем как вы впервые воспользуетесь новыми возможностями этого программного обеспечения.

Предположим, что вы приступаете к разработке программы, основанной на использовании библиотеки Mobile Information Device Profile (MIDP) для языка Java. Вы собираетесь сохранить некоторые данные в объекте RecordStore и затем извлечь их оттуда. Должны ли вы просто написать код в надежде на то, что он заработает? Это один из возможных методов разработки.

Есть альтернативный метод. Обратите внимание на то, что вы собираетесь использовать новый метод нового класса. Вместо того чтобы просто воспользоваться им внутри разрабатываемого вами кода, вы пишете небольшой тест, который позволяет вам убедиться в том, что API работает так, как вы того ожидаете. Таким образом, вы можете написать:


RecordStore store;


public void setUp() {

store = RecordStore.openRecordStore("testing", true);

}


public void tearDown() {

RecordStore.deleteRecordStore("testing");

}


public void testStore() {

int id = store.addRecord(new byte[] {5, 6}, 0, 2);

assertEquals(2, store.getRecordSize(id));

byte[] buffer = new byte[2];

assertEquals(2, store.getRecord(id, buffer, 0));

assertEquals(5, buffer[0]);

assertEquals(6, buffer[1]);

}


Если ваше понимание API совпадает с действительностью, значит, тест сработает с первого раза.

Джим Ньюкирк рассказал мне о проекте, в котором разработка тестов для обучения выполнялась на регулярной основе. Как только от сторонних разработчиков поступала новая версия пакета, немедленно запускались имеющиеся тесты. В случае необходимости в тесты вносились исправления. Если тесты завершались неудачей, не было никакого смысла запускать приложение, так как оно определенно не заработает. Если же все тесты выполнялись успешно, значит, и приложение заработает.

Еще один тест (Another Test)

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

Я люблю пространные дискуссии (вы уже прочитали большую часть книги, поэтому, скорее всего, пришли к такому же выводу самостоятельно). Если постоянно жестко следить за соблюдением основной темы обсуждения, можно потерять множество бриллиантовых идей. Вы перескакиваете с одной темы на другую, затем на третью и, наконец, не успеваете заметить, что ушли далеко от того, с чего начали. А кого это волнует, ведь обсуждать вещи в таком стиле – это круто!

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

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

Регрессионный тест (Regression Test)

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

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

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

Возможно, для того чтобы изолировать дефект, вам потребуется выполнить рефакторинг системы. В этом случае, демонстрируя дефект, система как бы говорит вам: «Ты еще не вполне закончил проектировать меня».

Перерыв (Break)

Что делать, если вы почувствовали усталость или зашли в тупик? Прервите работу и отдохните.

Выпейте кофе, пройдитесь или даже вздремните. Стряхните с себя эмоциональное напряжение, связанное с решениями, которые вы принимаете, и символами, которые вы набираете на клавиатуре.

Иногда самого короткого перерыва достаточно, чтобы недостающая идея возникла в вашей голове. Возможно, вставая из-за компьютера, вы неожиданно нащупаете нужную нить: «Да я же не попробовал этот метод с пересмотренными параметрами!» В любом случае прервитесь. Дайте себе пару минут. Идея никуда не убежит.

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

Дэйв Унгар (Dave Ungar) называет это Методологией душа (Shower Methodology). Если вы знаете, что писать, – пишите. Если вы не знаете, что писать, примите душ и стойте под ним до тех пор, пока не поймете, что нужно писать. Очень многие команды были бы более счастливыми, более продуктивными и пахли бы существенно лучше, если бы воспользовались этим советом.

TDD – это усовершенствование предложенной Унгаром методологии душа. Если вы знаете, что писать, пишите очевидную реализацию. Если вы не знаете, что писать, создайте поддельную реализацию. Если правильный дизайн по-прежнему не ясен, триангулируйте. Если вы по-прежнему не знаете, что писать, можете, наконец, принять душ.

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

Чтобы разорвать этот замкнутый круг, необходимо добавить дополнительный внешний элемент.

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


Рис. 26.1. Усталость негативно влияет на рассудительность, которая негативно влияет на усталость


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

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

• В масштабе года вы получаете отпуск, что позволяет вам полностью освежиться. Французы подходят к этому вопросу очень правильно – двух последовательных недель отпуска недостаточно. В течение первой недели вы сбрасываете с себя рабочее напряжение, а в течение второй недели подсознательно готовите себя к работе. Поэтому, чтобы хорошо отдохнуть и эффективно работать в течение всего следующего года, требуется три, а лучше четыре недели отдыха.