Плюс кажется, что необходимость
синхронизировать комплексный набор тестов
с постоянно меняющимся кодом будет
боль. Я понимаю, что блок
тестовый набор может очень помочь
во время обслуживания, как только программное обеспечение
построен, стабилен и функционирует, но
это поздно в игре, где TDD
должен помочь и на раннем этапе.
Я согласен с тем, что издержки, связанные с наличием комплекта модульных тестов, могут ощущаться при этих ранних изменениях, когда происходят серьезные архитектурные изменения, но я считаю, что преимущества от проведения модульных тестов намного перевешивают этот недостаток. Я думаю, что слишком часто проблема является ментальной - мы склонны думать о наших модульных тестах как о гражданах второго сорта кодовой базы, и мы возмущаемся, что им приходится возиться с ними. Но со временем, поскольку я стал полагаться на них и ценить их полезность, я начал думать о них как о не менее важных и не менее достойных техобслуживании и работе, как о любой другой части базы кода.
Являются ли главные архитектурные "изменения", происходящие действительно только рефакторингами? Если вы выполняете рефакторинг, хотя и резко, и тесты начинают проваливаться, это может указывать на то, что вы случайно изменили функциональность где-то. Это именно то, что модульные тесты должны помочь вам поймать. Если вы вносите радикальные изменения в функциональность и архитектуру одновременно, вы можете рассмотреть возможность замедления и перехода к этой красной / зеленой / канавке рефактора: никаких новых (или измененных) функций без дополнительных тестов и никаких изменений в функциональность (и тесты) при рефакторинге.
Обновление (на основе комментариев):
@ Cybis выдвинула интересное возражение против моего утверждения, что рефакторинг не должен нарушать тесты, потому что рефакторинг не должен изменять поведение. Он возражает, что рефакторинг меняет API и, следовательно, тестирует "break".
Во-первых, я бы посоветовал любому посетить каноническую ссылку на рефакторинг: Блики Мартина Фаулера . Только сейчас я рассмотрел это, и несколько вещей выскакивают из меня:
- Меняется интерфейс
рефакторинг? Мартин относится к
рефакторинг как
«сохраняющее поведение» изменение, которое
означает, когда интерфейс / API меняется
тогда все абоненты этого
Интерфейс / API также должен измениться.
Включая тесты, говорю я.
- Это не значит, что поведение изменилось. Опять же Фаулер подчеркивает, что его
Определение рефакторинга заключается в том, что
изменения поведения
сохранение .
В свете этого, если тест или тесты должны измениться во время рефакторинга, я не вижу в этом «нарушения» теста (ов). Это просто часть рефакторинга, сохранения поведения всей базы кода. Я не вижу разницы между изменением теста и любой другой частью базы кода, которая должна изменяться как часть рефакторинга. (Это восходит к тому, что я говорил ранее о том, что тесты должны быть первоклассными гражданами кодовой базы.)
Кроме того, я ожидаю, что тесты, даже модифицированные тесты, до продолжат проходить после завершения рефакторинга. Независимо от того, что тестировал этот тест (вероятно, утверждение (я) в этом тесте) должно оставаться действительным после проведения рефакторинга. В противном случае это красный флаг, который как-то изменял / регрессировал поведение во время рефакторинга.
Возможно, это утверждение звучит как бессмыслица, но подумайте об этом: мы ничего не думаем о перемещении блоков кода в базе производственного кода и ожидаем, что они продолжат работать в своем новом контексте (новый класс, сигнатура нового метода и т. Д.). Я чувствую то же самое в отношении теста: возможно, рефакторинг изменяет API, который должен вызывать тест, или класс, который тест должен использовать, но в конце точка теста не должна измениться из-за рефакторинга.
(Единственное исключение, о котором я могу подумать, это тесты, которые тестируют детали реализации низкого уровня, которые вы можете изменить во время рефакторинга, например, заменить LinkedList на ArrayList или что-то в этом роде. Но в этом случае можно поспорить что тесты являются чрезмерными, слишком жесткими и хрупкими.)