Есть тесты для поддержки и обеспечения защитного программирования
Защитное программирование защищает целостность системы во время выполнения.
Тесты (в основном статические) диагностические инструменты. Во время выполнения ваших тестов нигде не видно. Они похожи на леса, используемые для установки высокой кирпичной стены или каменного купола. Вы не оставляете важные части вне структуры, потому что у вас есть леса, которые удерживают его во время строительства. У вас есть леса, которые удерживают их во время строительства, чтобы облегчить установку всех важных деталей.
РЕДАКТИРОВАТЬ: аналогия
А как насчет аналогии с комментариями в коде?
Комментарии имеют свою цель, но могут быть избыточными или даже вредными. Например, если вы добавите в комментарии внутренние знания о коде , а затем измените код, комментарии в лучшем случае станут неактуальными, а в худшем - вредными.
Допустим, вы вложили в тесты много внутренних знаний о вашей кодовой базе, например, MethodA не может принимать значение NULL, а аргумент MethodB должен быть > 0
. Затем код меняется. Нуль в порядке для A сейчас, и B может принимать значения, такие как -10. Существующие тесты теперь функционально неверны, но будут продолжать проходить.
Да, вы должны обновлять тесты одновременно с обновлением кода. Вы также должны обновлять (или удалять) комментарии одновременно с обновлением кода. Но мы все знаем, что такие вещи не всегда случаются, и что ошибки сделаны.
Тесты проверяют поведение системы. Это фактическое поведение присуще самой системе, а не присуще тестам.
Что возможно могло пойти не так?
Цель тестов - продумать все, что может пойти не так, написать для него тест, который проверяет правильность поведения, а затем создать код времени выполнения, чтобы он прошел все тесты.
Что означает, что оборонительное программирование - это главное .
TDD управляет защитным программированием, если тесты комплексные.
Больше тестов, вождение более оборонительного программирования
Когда ошибки неизбежно обнаруживаются, пишется больше тестов для моделирования условий, которые проявляют ошибку. Затем код исправляется, с кодом, позволяющим выполнить эти тесты, и новые тесты остаются в наборе тестов.
Хороший набор тестов будет передавать как хорошие, так и плохие аргументы функции / методу и ожидать согласованных результатов. Это, в свою очередь, означает, что тестируемый компонент будет использовать проверки предварительных условий (защитное программирование) для подтверждения переданных ему аргументов.
Вообще говоря ...
Например, если нулевой аргумент определенной процедуры недействителен, то по крайней мере один тест будет проходить нулевое значение и будет ожидать исключения / ошибки «недопустимый нулевой аргумент» некоторого вида.
Конечно, по крайней мере, еще один тест должен передать действительный аргумент - или перебрать большой массив и передать множество допустимых аргументов - и подтвердить, что полученное состояние является подходящим.
Если тест не передает этот нулевой аргумент и получает удар с ожидаемым исключением (и это исключение было сгенерировано, потому что код защитно проверил переданное ему состояние), тогда нулевое значение может в конечном итоге быть присвоено свойству класса или похоронено в какой-то коллекции, где это не должно быть.
Это может привести к неожиданному поведению в какой-то совершенно другой части системы, в которую передается экземпляр класса, в некотором отдаленном географическом регионе после поставки программного обеспечения . И это именно то, чего мы на самом деле пытаемся избежать, верно?
Это может быть даже хуже. Экземпляр класса с недопустимым состоянием может быть сериализован и сохранен только для того, чтобы вызвать сбой, когда он будет восстановлен для последующего использования. Боже, я не знаю, может быть, это какая-то механическая система управления, которая не может перезапуститься после выключения, потому что она не может десериализовать свое собственное постоянное состояние конфигурации. Или экземпляр класса может быть сериализован и передан какой-то совершенно другой системе, созданной другим объектом, и эта система может аварийно завершить работу.
Особенно, если программисты этой другой системы не защитили код.