Для написания тестов есть две причины:
- Утверждение ожидаемого поведения
- Предотвращение регрессии поведения
Взятие на себя (1) Утверждение ожидаемого поведения:
Когда вы утверждаете ожидаемое поведение, вы хотите убедиться, что код работает так, как вы думаете. По сути, это автоматизированный способ выполнения вашей обычной ручной проверки, которую любой разработчик будет выполнять при реализации любого вида кода:
- Разве то, что я только что написал, работает?
- Закончился ли этот цикл?
- Это зацикливание в том порядке, в котором я думаю?
- Будет ли это работать для нулевого ввода?
На эти вопросы мы все отвечаем в своих головах, и обычно мы пытаемся выполнить код и в наших головах, чтобы убедиться, что он работает. В этих случаях часто бывает полезно, чтобы компьютер отвечал на них определенным образом. Поэтому мы пишем модульный тест, который утверждает, что это делает. Это вселяет в нас уверенность в нашем коде, помогает нам быстрее находить дефекты и даже может помочь в реализации кода.
Это хорошая идея, делать это там, где вы чувствуете, что это необходимо. Любой код, который немного сложно понять, или нетривиален. Даже тривиальный код может извлечь из этого пользу. Все дело в твоей уверенности. Как часто это делать и как далеко идти, будет зависеть от вашего собственного удовлетворения. Остановитесь, когда сможете с уверенностью ответить Да на: Вы уверены, что это работает?
Для такого рода тестирования вам не важны видимость, интерфейсы или что-то подобное, вам нужно только наличие рабочего кода. Так что да, вы бы протестировали частные и защищенные методы, если бы чувствовали, что их необходимо проверить, чтобы вы ответили «Да» на вопрос.
Взятие на себя (2) Предотвращение регрессии поведения:
После того, как вы получили рабочий код, у вас должен быть механизм для защиты этого кода от будущего повреждения. Если бы никто больше не трогал ваш источник и ваш конфиг, вам это не понадобилось бы, но в большинстве случаев вы или другие люди будут касаться источника и конфигов вашего программного обеспечения. Эта внутренняя путаница, скорее всего, сломает ваш рабочий код.
Механизмы существуют на большинстве языков уже как способ защиты от этого ущерба. Функции видимости являются одним механизмом. Закрытый метод изолирован и скрыт. Инкапсуляция - это еще один механизм, в котором вы разделяете вещи, поэтому изменение других частей не влияет на другие.
Общий механизм для этого называется: кодирование до границы. Создавая границы между частями кода, вы защищаете все внутри границы от вещей за ее пределами. Границы становятся точкой взаимодействия и контрактом, по которому вещи взаимодействуют.
Это означает, что изменение границы, либо нарушив ее интерфейс, либо нарушив его ожидаемое поведение, повредит и, возможно, нарушит другие границы, на которые он опирается. Вот почему хорошая идея иметь модульный тест, который нацелен на эти границы и утверждает, что они не меняются ни в семантическом, ни в поведении.
Это типичный юнит-тест, о котором все чаще говорят, когда упоминают TDD или BDD. Дело в том, чтобы укрепить границы и защитить их от изменений. Вы не хотите тестировать закрытые методы для этого, потому что закрытый метод не является границей. Защищенные методы - это ограниченная граница, и я бы их защитил. Они не выставлены миру, но все еще выставлены другим отделениям или "Единицам".
Что с этим делать?
Как мы видели, есть веская причина для модульного тестирования открытых и защищенных методов, чтобы утверждать, что наши интерфейсы не меняются. И есть также веская причина для тестирования частных методов, чтобы утверждать, что наша реализация работает. Так стоит ли нам их всех тестировать?
Да и нет.
Во-первых : протестируйте все методы, которые, по вашему мнению, нуждаются в убедительном доказательстве того, что он работает в большинстве случаев, чтобы быть уверенным в том, что ваш код работает, независимо от видимости.Затем отключите эти тесты.Они сделали там работу.
Наконец : напишите тесты для ваших границ.Проведите юнит-тест для каждой точки, которая будет использоваться другими блоками вашей системы.Убедитесь, что этот тест подтверждает семантический контракт, имя метода, количество аргументов и т. Д. А также убедитесь, что тест подтверждает доступное поведение модуля.Ваш тест должен продемонстрировать, как использовать устройство и что оно может делать.Сохраняйте эти тесты включенными, чтобы они выполнялись при каждом нажатии кода.
ПРИМЕЧАНИЕ. Причина, по которой вы отключили первый набор тестов, состоит в том, чтобы разрешить выполнение работы по рефакторингу.Активный тест - это кодовая связь.Это предотвращает будущие изменения кода, который он тестирует.Это требуется только для ваших интерфейсов и контрактов на взаимодействие.