TDD — это непросто, как и кодирование…

Есть интересная дискуссия, в которой я принимал участие относительно Test Driven Design (TDD), популярной практики программирования. Тема утверждает, что эта практика проста, и я хочу подробно рассказать о своем опыте и истории в этой статье. Мое намерение состоит не в том, чтобы пристыдить любого, кто добился успеха или неудачи с помощью этой методологии, а в том, чтобы осветить одно из самых больших недоразумений, широко распространенных в отрасли.

Позвольте мне начать с напоминания всем, что программирование — это непросто. Хотя многие из нас находят радость и удовлетворение в этой карьере, есть причина, по которой зарплаты в районе залива (и в других районах) такие высокие. Написание кода требует определенной дисциплины и мышления, которых нет у многих людей. Если вы терпеливы и методичны, вы действительно сможете разобраться в самом сложном замысле. Однако, если вы не знакомы с логическими рассуждениями или не чувствуете себя комфортно, вы столкнетесь с разочарованием и с высокой вероятностью сдадитесь. Это не означает, что вы неспособны, недальновидны или некомпетентны. Это говорит только о вашем знакомстве и особом образе мышления. Некоторые люди или логичны, некоторые артистичны, а третьи имеют вкрапления художественного творчества и логики.

Теперь поговорим о дизайне через тестирование. Я провел большую часть своей 22-летней карьеры, проповедуя и пытаясь привлечь различные команды к работе с TDD. Я видел, как он преуспел в проектах, и видел, как он терпит неудачу. Практически в каждом сценарии, где он дал сбой, я заметил определенную закономерность. Это никогда не бывает неудачей из-за недостатка усилий, способностей или когнитивных способностей. Скорее инженеру (или всей команде) не удалось изменить мышление. В этом заключается БОЛЬШОЕ недоразумение.

На самом деле вам нужно мышление не разработчика, чтобы преуспеть в TDD. Другими словами, вы должны перестать думать как разработчик, чтобы добиться успеха с этой концепцией разработки! Позвольте этому погрузиться на мгновение. Я хочу вернуться к этому моменту, но сначала немного отвлекусь.

Мы, инженеры, рождены и выросли, чтобы решать проблемы! Мы гордимся тем, как быстро и блестяще можем предложить техническое решение любой проблемы, и мы зациклены на деталях! Вся наша природа состоит в том, чтобы давать ответы! Мы настолько хороши в этом, что даем ответы еще до того, как вопрос задан! Мы даем ответы на вопросы, которые никогда не задавались! У вас есть куча данных, которые вы хотите обработать? Нет проблем, добавьте его в базу данных NoSQL SQL! Подождите, это тяжело читать или в основном писать? У нас есть конфигурация для обоих! Позвольте мне разделить эту БД для вас! Вам необходимо распространять HD-видео и мультиплексированное аудио для широкой аудитории в режиме реального времени с нулевой задержкой! Прямо сейчас есть парень с специально приготовленным сервисом UDP и совершенно новым протоколом, ожидающий по телефону! Именно так живут и дышат большинство разработчиков!

Так что же значит практиковать Test Driven Design? Не буду лезть в дебри на эту тему, но на высоком уровне это означает одно. Мы сосредоточимся на требованиях и оставим технические детали на потом. Дизайн через тестирование, выполненный должным образом, представляет собой практику «снаружи внутри», которая фокусируется на вопросе. (Я хочу подчеркнуть, что сделано правильно, потому что я до сих пор спорю с некоторыми разработчиками, которые утверждают, что они сторонники, но не понимают, почему вы не можете сделать это изнутри.) TDD — это одержимость вопрос, а не ответ! «Что мы строим? Почему мы его строим? Кто им пользуется?» Вся предпосылка TDD на самом деле вовсе не связана с тестированием. Вот почему у вас будет большое количество людей, утверждающих, что это легко. Заблуждение состоит в том, что писать тесты легко.

Позвольте мне сказать это так. Написание тестов может быть довольно простым, однако это не то же самое обсуждение. Если вы тестируете свой код, вероятно, вы не применяете TDD. Вы можете иметь 90–100% покрытие тестами и НЕ использовать TDD. Я видел это на практике, и это действительно легко упустить из виду. Если мы преуменьшим акцент на тестировании, то фокус и неправильное представление будет немного легче увидеть.

Я напишу так: «tdD». Последняя буква «D» в аббревиатуре относится к «Дизайну» и является наиболее значимой. Весь смысл TDD заключается в том, чтобы управлять дизайном вашего кода, случайно используя тестовую среду. Правильно, случайно сказал! Некоторые умные люди давно поняли, что для этого даже не нужно использовать тестовую среду. Они рассудили, что вы можете использовать то, что часто отсутствует в большинстве компаний: документ с требованиями или формальную спецификацию пользователя! (Есть ли в вашем проекте последняя версия одного из них?) Эта идея привела к появлению таких инструментов, как FitNesse, R-spec и новой аббревиатуры BDD. Принцип тот же. Мы хотим перейти от требований или спецификации к коду и обратно. Я не буду подробно останавливаться на деталях, лежащих в основе TDD и BDD. Вместо этого я оставлю это для другой статьи.

Если тестирование вашего кода на самом деле не является частью TDD, неудивительно, что так много людей испытывают трудности! Я действительно пытаюсь продвинуть тонкий момент здесь. Вокруг TDD так много разных идей и принципов, что это может легко поранить нерв. На самом деле существует большое количество разработчиков и сторонников TDD, которые упускают суть TDD и фактически выступают за написание тестов. Это население технически не ошибается, когда считает, что писать тесты и тестировать код легко. Это то самое население сообщества, которое еще не освоило самую сложную часть TDD. Они женаты на технических деталях инструментов и не проделывали умственную гимнастику, необходимую для осмысления фактической практики. Должен сказать, тестирование — это круто, и у нас есть для этого действительно надежный инструмент. Трудно указать на это, потому что это все равно, что сказать императору, что он голый. У меня было несколько оживленных дискуссий на эту тему, и она никуда не ушла.

Это возвращает меня к моей исходной точке. Вы должны ПРЕКРАТИТЬ думать как разработчик, чтобы понять или добиться успеха с TDD! Сказать разработчику, чтобы он не думал о тестировании и начал думать о спецификациях продукта как части TDD, — это все равно, что учить рыбу летать или учить птицу плавать! Это ужасная/великолепная аналогия, потому что есть несколько летающих рыб и много плавающих птиц. Дело в том, что большинство птиц остаются в основном вне воды, в то время как большинство рыб избегают неба. Итак, хотя может быть легко показать кому-то, как писать тест, вы когда-нибудь пытались сказать разработчику, чтобы он закрыл свой редактор, удалил код или сначала начал снаружи? Если да, то вы поймете, насколько уникален и сложен в обучении TDD! Вы должны научить разработчика не думать как разработчик!

Хочу закончить на очень спорной ноте. Честно говоря, я не думаю, что многие проекты должны использовать TDD. Не поймите меня неправильно! Я люблю практику и всегда продвигаю тестирование больше, чем большинство людей! Тем не менее, я чувствую, что на самом деле нет ничего плохого в разработчиках/командах, которые не практикуют настоящий TDD. Философия достаточно сложна, когда сопутствующие затраты часто перевешивают выгоды. У меня было много успешных проектов и команд. Некоторые из них используют его, а многие нет. Хотя я чувствую, что большинство (если не все) проектов, над которыми я работал, могли бы выиграть от TDD, инвестиции и усилия, чтобы сделать это правильно в средней и большой команде, довольно значительны из-за всего, что я изложил выше. Как инженер, я всегда считаю, что TDD — лучший подход, но как менеджер я всегда сопоставляю затраты и потенциальный отказ с теоретическими преимуществами. Как человек, побывавший по обе стороны баррикад, я не могу игнорировать тот факт, что многим проектам, вероятно, следует этого избегать.

(Недавно я выступил с докладом, в котором призвал всю свою команду изучить Test Driven Design, чтобы мы могли начать его использовать!)