С TDD вас не волнует дизайн. Идея состоит в том, что вы должны сначала узнать, что вам нужно, прежде чем начинать с полезного дизайна. Тесты позволят вам легко и надежно изменить свое приложение, когда придет время, когда вам нужно определиться с дизайном.
Без TDD это происходит: вы делаете дизайн (который, вероятно, слишком сложен в некоторых областях, плюс вы забыли принять во внимание некоторые важные факты, так как не знали о них). Затем вы начинаете реализацию дизайна. Со временем вы осознаете все недостатки вашего дизайна, поэтому вы его меняете. Но изменение дизайна не изменит вашу программу. Теперь вы пытаетесь изменить свой код в соответствии с новым дизайном. Поскольку код не был написан так, чтобы его можно было легко изменить, это в конечном итоге приведет к сбою, в результате чего у вас останется два проекта (один сломан, а другой в неизвестном состоянии) и код, который тоже не подходит.
Чтобы начать с TDD, включите ваши требования в тест. Для этого спросите: «Откуда мне знать, что это требование выполнено?» Если вы можете ответить на этот вопрос, напишите тест, который реализует ответ на этот вопрос. Это дает вам API, которому должен соответствовать ваш (подлежащий написанию) код. Это очень простой дизайн, но он всегда работает и б) гибок (потому что вы не можете протестировать негибкий код).
Также, начиная с теста, вы станете вашим собственным клиентом. Поскольку вы очень стараетесь сделать тест как можно более простым, вы создадите простой API, который заставит тест работать.
И со временем вы узнаете достаточно о своей проблемной области, чтобы иметь возможность создать реальный дизайн. Поскольку у вас есть много тестов, вы можете изменить свой код в соответствии с дизайном. Не ломая ничего на пути.
Это теория :-) На практике вы столкнетесь с парой проблем, но она работает довольно хорошо. Или, скорее, это работает лучше, чем что-либо еще, с чем я столкнулся.