Очень конкретный вопрос от новичка к TDD:
Я разделяю свои тесты и свое приложение в различные пакеты. Таким образом большинство моих методов приложения должно быть открытым, чтобы тесты получили доступ к ним. В то время как я прогрессирую, становится очевидно, что некоторые методы могли стать частными, но если я вношу то изменение, тесты, что доступ их не будет работать. Я пропускаю шаг, или делаю что-то не так или являюсь этим всего одно крушение TDD?
Это не крушение TDD, а скорее подход к тестированию, который считает, что вам нужно тестировать каждое свойство и каждый метод. На самом деле вам не следует заботиться о частных методах при тестировании, потому что они должны существовать только для поддержки некоторой общедоступной части API.
Никогда не меняйте что-либо с частного на общедоступное в целях тестирования!
Вам следует проверять только публично видимое поведение. Остальное - это детали реализации, и вы специально не хотите их тестировать. TDD предназначен для предоставления вам набора тестов, которые позволят вам легко изменить детали реализации без нарушения тестов (изменение поведения).
Допустим, у меня есть тип: MyClass
, и я хочу протестировать метод DoStuff
. Меня волнует только то, что метод DoStuff
делает что-то значимое и возвращает ожидаемые результаты. Он может вызвать сотню частных методов, чтобы добраться до этой точки, но меня как потребителя этого метода не волнует.
Вы не указали, какой язык вы используете, но, конечно, в большинстве из них вы можете разместить тесты таким образом, чтобы иметь более привилегированный доступ к классу. В Java, например, тест может находиться в том же пакете, а файл класса - в другом каталоге, чтобы он был отделен от производственного кода.
Однако, когда вы делаете настоящий TDD, тесты определяют дизайн класса, поэтому если у вас есть метод, который существует только для тестирования некоторого подмножества функциональности, вы, вероятно (не всегда), делаете что-то неправильно, и вам следует обратить внимание на такие техники, как инъекция зависимостей и мокинг, чтобы лучше направлять ваш дизайн.
Здесь часто всплывает старая поговорка «TDD - это про дизайн». Класс со слишком большим количеством общедоступных методов, вероятно, имеет слишком много обязанностей - и тот факт, что вы тестируете его, только демонстрирует это; это не вызывает проблемы.
Когда вы попадаете в такую ситуацию, часто лучшим решением является поиск некоторого подмножества общедоступных методов, которые могут быть извлечены в новый класс («sprout class»), а затем дать вашему исходному классу переменную экземпляра проросшего класс. Публичные методы заслуживают того, чтобы быть общедоступными в новом классе, но теперь они - по сравнению с API исходного класса - частными. И теперь у вас лучшее соблюдение SRP, более слабая связь, меньшая связность - лучший дизайн.
Все потому, что TDD раскрыл возможности вашего класса, которые в противном случае остались бы незамеченными. TDD посвящен дизайну .
По крайней мере, в Java, хорошей практикой является иметь два дерева исходников, одно для кода и одно для тестов. Поэтому вы можете поместить код и тесты в один пакет, хотя они все еще находятся в разных каталогах:
src/org/my/xy/X.java
test/org/my/xy/TestX.java
Затем вы можете сделать пакет методов приватным.