Debug.Assert против использования кода контракта

Когда я должен отладить.assert над контрактами кода или наоборот? Я хочу проверить предварительные условия для метода, и я не могу выбрать один из других. У меня есть модульные тесты, где я хочу протестировать сценарии сбоев и ожидать исключений.

Является ли хорошей практикой использовать контракт Debug.Assert и Code для одного и того же метода. Если так, каков будет порядок написания кода?

Debug.Assert(parameter!= null);
Contract.Requires<ArgumentNullException>(parameter != null, "parameter");

или же

Contract.Requires<ArgumentNullException>(parameter != null, "parameter");
Debug.Assert(parameter!= null);

Есть ли за этим обоснование?

2 ответа

Решение

Это разные вещи. Отладочное утверждение выполняется только тогда, когда код скомпилирован как отладочный, и поэтому будет проверять / утверждать только при отладке. Идея состоит в том, чтобы использовать это для проверки работоспособности кода, который вы разрабатываете. Контракты кода могут использоваться либо в отладке, либо в выпуске. Они гарантируют, что предварительные и последующие условия методов соответствуют ожиданиям метода (соответствуют контракту). Существует также инфраструктура тестирования, которая предоставляет аналогичные функциональные возможности и предназначена для проверки соответствия тестов.

Используйте Debug.Assert, когда вы хотите убедиться, что определенные вещи соответствуют вашим ожиданиям при разработке кода (и при дальнейшей разработке обслуживания).

Используйте контракты кода, когда хотите убедиться, что условия выполняются как в отладке, так и в выпуске. Контракты также допускают определенные формы статического анализа, которые могут быть полезны при проверке правильности вашей программы.

Используйте утверждения инфраструктуры тестирования при создании модульных тестов.

Лично я бы не использовал оба Debug.Assert И кодовые контракты для обеспечения выполнения предварительных условий во вновь создаваемом коде - кодовые контракты ИМО заменяют собой Debug.Assertпоскольку они предлагают более полный набор проверок, не говоря уже о преимуществах, которые могут быть получены от статической проверки, которая может быть выполнена до того, как код будет запущен во время выполнения. Поддержание дубликатов проверки предварительных условий в обоих Debug.Assert а также Contracts будет громоздким

Обоснование:

  • Вам не нужно перекодировать какие-либо устаревшие предварительные условия, которые вы, возможно, закодировали в Debug.Assert или же throw код - вы можете сохранить существующий код проверки предусловия и завершить его с помощьюContract.EndContractBlock()
  • Вы можете получить то же непроверенное поведение "режима выпуска", когда System.Diagnostics.Debug построен без /d:DEBUG если вы строите с проверкой времени выполнения контракта, установленной на None, Ссылка 6.2.1 в Документах
  • Контракты позволяют разработчику быть более выразительным в коде относительно того, "почему" было обнаружено недопустимое состояние - например, было ли это напрямую из-за внеполосного параметра (Contract.Requires). Иначе Contract.Assert или же Contract.Assume может проверить общее состояние, а "гарантированная правильность" состояния при выходе из метода может быть выражена с помощью Contract.Ensures, А также Invariants выразить, что государство должно проводиться в любое время.
  • И что лучше всего, статическая проверка может обеспечить выполнение этих контрактов при создании кода - таким образом, у вас есть возможность обнаружить ошибку во время разработки или предупреждения о времени компиляции вместо того, чтобы ждать выполнения. Контрактные чеки могут быть добавлены к вашей непрерывной интеграции для поиска несоответствия.

Одно предостережение: если вы собираетесь писать модульные тесты, которые намеренно нарушают контракты, вам, возможно, придется иметь дело с ContractException - Джон Скит объясняет это хорошо здесь. например, подключить Contract.ContractFailed обработчик в вашей тестовой настройке к обработчику, который вызывает SetHandled а затем выдает публичное исключение, которое вы можете поймать и утвердить в своем UT.

Другие вопросы по тегам