Я думал, что добавлю еще четыре случая, когда Debug.Assert может быть правильным выбором.
1) Что-то, что я не видел, упомянуто здесь, это дополнительное концептуальное покрытие, которое Asserts может обеспечить во время автоматического тестирования . В качестве простого примера:
Когда автор звонка модифицирует вызывающего абонента более высокого уровня, он считает, что они расширили область действия кода для обработки дополнительных сценариев, в идеале (!) Они будут писать модульные тесты, чтобы охватить это новое условие. Тогда может показаться, что полностью интегрированный код работает нормально.
Однако на самом деле был обнаружен тонкий дефект, но он не обнаружен в результатах испытаний. Вызываемый стал недетерминированным в этом случае, и только происходит , чтобы обеспечить ожидаемый результат. Или, возможно, это привело к ошибке округления, которая была незамеченной. Или вызвал ошибку, которая была одинаково смещена в другом месте. Или предоставляется не только запрошенный доступ, но и дополнительные привилегии, которые не должны предоставляться. Etc.
На этом этапе операторы Debug.Assert (), содержащиеся в вызываемом объекте в сочетании с новым регистром (или граничным регистром), инициированным модульными тестами, могут предоставить неоценимое уведомление во время теста о том, что исходные предположения автора были признаны недействительными, и код не должен быть выпущен без дополнительного рассмотрения. Активы с юнит-тестами - идеальные партнеры.
2) Кроме того, некоторые тесты просты в написании, но дорогостоящи и не нужны, если исходные предположения . Например:
Если доступ к объекту возможен только из определенной защищенной точки входа, следует ли выполнять дополнительный запрос к базе данных сетевых прав из каждого метода объекта, чтобы убедиться, что у вызывающей стороны есть разрешения? Конечно, нет. Возможно, идеальное решение включает кеширование или какое-то другое расширение функций, но дизайн не требует этого. Debug.Assert () немедленно покажет, когда объект был прикреплен к небезопасной точке входа.
3) Далее, в некоторых случаях ваш продукт может не иметь полезного диагностического взаимодействия для всех или части его операций при развертывании в режиме выпуска . Например:
Предположим, это встроенное устройство реального времени. Создание исключений и перезапуск при обнаружении неверно сформированного пакета неэффективно. Вместо этого устройство может извлечь выгоду из работы с максимальным усилием, даже до точки рендеринга шума на его выходе. Он также может не иметь человеческого интерфейса, регистрирующего устройства или даже быть физически недоступным для человека вообще при развертывании в режиме выпуска, и понимание ошибок лучше всего обеспечить путем оценки того же результата. В этом случае либеральные утверждения и тщательное предварительное тестирование более ценны, чем исключения.
4) Наконец, некоторые тесты являются ненужными только потому, что вызываемый объект воспринимается как чрезвычайно надежный . В большинстве случаев, чем больше повторного использования кода, тем больше усилий было приложено, чтобы сделать его надежным. Следовательно, для исключения характерны непредвиденные параметры от вызывающих абонентов, а для ожидаемых результатов от вызывающих - обычное явление. Например:
Если основная операция String.Find
сообщает, что она вернет -1
, когда критерии поиска не найдены, вы можете безопасно выполнить одну операцию вместо трех. Однако, если оно действительно вернуло -2
, у вас может не быть разумных действий. Было бы бесполезно заменять более простой расчет на тот, который проверяет отдельно значение -1
, и в большинстве сред релизов нецелесообразно засорять ваш код тестами, обеспечивающими работу основных библиотек, как ожидается. В этом случае утверждения идеальны.