Мя тут немного почитал, немного посмотрел и немного поговнокодил, и что-то не складывается каменный цветок. Выглядит оно это ваше TDD как учебная методика, форсирующая приобретение навыков создания тестируемого дизайна и на своём примере показывающая, насколько больно поддерживать хрупкие тесты, но не как реальный способ разрабатывать сложный функционал.
В целом, вопросные тезисы и тезисные вопросы таковы:
- С чего начинать? Как выбрать фичу, к написанию теста на которую приступить в первую очередь? Как не попасть в ситуацию «написал приёмочный тест вместо красивого чёткого TDD, ну ты лох», о которой многие упоминают, но не рассказывают, как правильно? Практически все мануалы показывают написание теста сразу для фичи верхнего уровня, что, КМК, приёмочным/дымовым тестом и является.
- Написание теста для функционала, решение которого нетривиально, вынуждает писать тонны заглушек просто чтобы «скомпилируйся наконец уже пожалуйста». Количество заглушек умножается на количество «baby steps» при рефакторинге и добавлении новых тестов, генерируя адский объём механической работы. Определённо, значительная часть таких затыков порождена моей дизайнерской криворукостью, но мя не вижу способа полностью избежать этого рака.
- Как TDD предлагает «пробивать» инкапсуляцию, когда функционал под тестом оказывается нетривиальным и требует вынесения части функционала в новую сущность? Многие статьи демонстрируют погрузку болта на внутреннюю сложность реализации, тестируя только контракт, что выглядит очевидно неправильным. Имеет ли концептуально реализация право порождать новый тест? Нужно ли, когда в ходе рефакторинга или позеленевания тестов требуется создать что-то новое, откладывать текущую работу над реализацией и идти писать новый тест для свежеобозначившейся проблемы? Что делать, когда поймёшь, что погряз в огромном объёме некомпилируемого кода и незапускающихся тестов?
- Некоторые авторы предлагают следующий рекурсивненький жизненный цикл: ставим задачу верхнего уровня, решаем её. Если не удаётся за вменяемое время написать тест/реализацию, дропаем текущие наработки, собираем митап и распиливаем её на подзадачи, далее работаем с ними. Это выглядит минимально-рабочим, но вызывает вопросы: как планировать время на реализацию фичи, как рефакторить функционал более верхнего уровня, если он окажется концептуально неправильным, как избежать лавинообразного рефакторинга с проблемой кучи некомпилируемого кода, чем безумно дорогая по времени перековка какашки в конфетку лучше, классического предварительного планирования с UML и быстрого написания прототипов отдельных штуковин.
TLDR: «под капотом» TDD очень сильно напоминает наивное «не надо ничего планировать, щас что-нибудь в процессе выдумаю», прикрытое сверху идеологией тестирования и горстью баззвордов. При попытке использовать его на не-совсем-тривиальном-проекте, который уже нельзя полностью держать в памяти, количество забытых нереализованных фунций и количество неожиданно всплывающей работы по рефакторингу и реимплементации превышают все мыслимые пределы. Это выглядит полезным для обучения, но не для реальной разработки.
Change my mind, как говорится, если есть желание. Мя ещё не зафиксировал какого-то конечного мнения о сабже, но первые впечатления смешанные.