Теперь вы столкнулись с тем, что для прохождения теста нужно перепроектировать код. Вы смотрите на часы и понимаете, что тестирование длится слишком долго. Поскольку вы уже тестировали все вручную и знаете, что все работает, то просто уходите прочь, оставляя еще один пробел в тестовом наборе. А вот когда вы сначала пишете тест, то все происходит совершенно иначе. У вас просто не получится написать функцию, которую трудно протестировать. Поскольку вы сначала пишете тест, то естественным образом проектируете функцию так, чтобы ее легко было протестировать. Как писать функции так, чтобы они были легко тестируемы? Нужно убрать связи между ними. Тестируемость означает свободу от связей.
Когда вы сначала пишете тесты, то размыкаете связи внутри программы таким способом, о котором бы никогда даже не подумали. Программа будет тестируема целиком, то есть связи между функциями всей программы будут отсутствовать.
Именно по этой причине разработку через тестирование часто называют методом проектирования. Три правила в высшей мере способствуют уменьшению связанности.
Смелость
Пока мы видели, что если следовать трем правилам разработки через тестирование, то у нас появляется много преимуществ: меньше отладки, качественная низкоуровневая документация, радость и разделение связей. Но это лишь сопутствующие преимущества, ни одно из них не является главной причиной применения разработки через тестирование. Настоящая причина — это воспитание смелости.
Я уже рассказывал историю в самом начале книги, но стоит ее повторить.
Представьте, что вы смотрите на некий уже написанный код на экране. Там бардак. Первая мысль, которая приходит в голову: «Нужно почистить его». Но следующая мысль будет примерно такой: «Нет, я в это не полезу!» Вы думаете, что если влезть в код, то он перестанет работать. А если он перестанет работать, вина ваша. Поэтому вы отстраняетесь от кода подальше, оставляя его гнить и чахнуть.
В вас говорит страх. Вы боитесь кода. Боитесь что-либо делать с ним. Боитесь что-то сломать, потому что будут последствия. Так вы отказываетесь от того единственного, что может улучшить код, — от его чистки.
Если в команде каждый придерживается такого поведения, код будет портиться. Никто не возьмется его почистить. Никто не улучшит его. Каждая новая функция будет добавлена таким образом, чтобы свести на нет непосредственный риск для программистов. Будут добавлены связи и дубликаты, потому что они уменьшают непосредственный риск, даже если нарушают структуру и целостность кода.
В конце концов код становится чудовищно запутанным, как спагетти, его невозможно сопровождать, работа над таким кодом едва ли будет продвигаться. Сложность задач будет расти в геометрической прогрессии. Менеджеры в отчаянии. Они будут нанимать все больше программистов в надежде улучшить производительность, но улучшение не будет достигнуто.
Наконец, достигнув критической точки, руководство согласится на требование программистов переписать всю программу с самого начала. И начинается то же самое.
Представьте себе другой сценарий. Вернемся к монитору, на котором мы видим запутанный код. Первая мысль, которая вас посещает, — надо почистить код. Что, если бы у вас был настолько полный тестовый набор, что ему можно полностью доверять? А если этот тестовый набор работал бы быстро? Что бы вы подумали следующим делом? Наверное, что-то вроде этого:
Когда у вас есть полный набор тестов, вы больше не боитесь вносить изменения в код. Вы больше не боитесь его чистить. Вы просто возьмете и почистите код. Код будет опрятным и чистым. Структура программы останется неизменной. Вы не будете плодить массу гниющего спагетти, которая вгонит команду в уныние, приводящее к низкой производительности и, в конце концов, к провалу.
Поэтому мы применяем разработку через тестирование. Мы применяем этот метод, потому что он вселяет в нас смелость поддерживать код в чистоте и порядке. Смелость вести себя профессионально.
Рефакторинг
Рефакторинг — еще одна тема, достойная целой книги. К счастью, ее уже написал Мартин Фаулер[53]. В этой главе мы просто обсудим это тему, не углубляясь в отдельные методы. И как и прежде, в этой главе нет кода.