Тестовые случаи И утверждения

Код этот вопрос заставлял меня думать

assert(value>0); //Precondition
if (value>0)
{
  //Doit
}

Я никогда не пишу if-statement. Утверждение достаточно/все, что вы можете сделать. "Сбой рано, часто сбой"

CodeComplete утверждает:

  • Утверждение-выражение делает приложение правильным
  • В случае if-теста приложение Robust

Я не думаю, что вы сделали приложение более надежным, исправив недопустимые входные значения или пропустив код:

assert(value >= 0 );  //Precondition
assert(value <= 90);  //Precondition
if(value < 0)         //Just in case
  value = 0;
if (value > 90)       //Just in case
  value = 90;
//Doit

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

Перефразировать CodeComplete: "Реальные программы становятся слишком грязными, когда мы не полагаемся исключительно на утверждения".

Вопрос: Я ошибаюсь, тупоумный, глупый, слишком не защищенный...

Ответ 1

Проблема с доверенным только утверждением заключается в том, что они могут быть отключены в рабочей среде. Чтобы процитировать статью в википедии:

Большинство языков позволяют утверждать, что включен или отключен глобально, и иногда независимо. Утверждения часто включаются во время разработки и отключены во время окончательного тестирования и по выпуску клиенту. Не проверка утверждений, избегающих стоимости оценки утверждений, в то время как, предполагая, что утверждения свободны от побочные эффекты, которые все еще производят одинаковые результат при нормальных условиях. Под ненормальные условия, отключение проверка утверждений может означать, что программа, которая была бы прервана, будет продолжать работать. Это иногда предпочтительнее. Wikipedia

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

Ответ 2

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

Использовать операторы if для проверки входных данных, которые вы не контролируете: общедоступные интерфейсы, предназначенные для потребления пользователем, тестирование ввода пользователя и т.д.

Проверьте ваше приложение с встроенными утверждениями. Затем разверните без утверждений.

Ответ 3

В некоторых случаях утверждения запрещены при создании для выпуска. У вас может не быть контроля над этим (иначе вы могли бы строить с утверждениями), поэтому было бы неплохо сделать это так.

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

Я обычно генерирую исключение в if-statement, чтобы взять на себя роль assert в случае, если они отключены

assert(value>0);
if(value<=0) throw new ArgumentOutOfRangeException("value");
//do stuff

Ответ 4

Я бы не согласился с этим утверждением:

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

Caller может подумать, что он знает, что входное значение верное. Только автор метода знает, как он должен работать. Лучшей целью программиста является заставить клиента попасть в " ядро ​​успеха". Вы должны решить, какое поведение более уместно в данном случае. В некоторых случаях ошибочные входные значения могут быть прощены, в другом случае вы должны исключать ошибку возврата.

Что касается Asserts, я бы повторил других комментаторов, assert - это проверка времени отладки для автора кода, а не для клиентов кода.

Ответ 5

Если я правильно помню из CS-класса

Предпосылки определяют, на каких условиях определяется выход вашей функции. Если вы создадите функцию errconditions для вашей функции, ваша функция будет определена для этого условия, и вам не понадобится инструкция assert.

Итак, я согласен. Обычно вам не нужны оба.

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

Ответ 6

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

Если, с другой стороны, вы не пишете логику для обработки всех случаев (возможно, из-за того, что нецелесообразно пытаться и продолжать с недопустимым вводом), тогда я буду использовать утверждение assertion и перейти к подходу "fail early".

Ответ 7

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

Проверьте входы, которые происходят извне с if-conditions. Внешне это где-нибудь вне кода, который вы/ваша команда контролируете и проверяете.

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

Ответ 8

Я должен был сказать, что я знал о том, что утверждает (здесь) исчезает в производственном коде.

Если if-statement фактически исправляет недопустимые входные данные в производственном коде, это означает, что assert никогда не удалялся во время тестирования кода отладки, это означает, что вы написали код, который вы никогда не выполняли.

Для меня это ситуация ИЛИ:

(quote Andrew) "защитите от всех диапазонов недопустимого ввода, я бы не стал беспокоиться об этом в первую очередь". → написать if-test.

(quote aku) "неправильные входные значения могут быть прощены" → написать assert.

Я терпеть не могу обоих...

Ответ 9

Проблема с утверждениями заключается в том, что они могут (и обычно будут) скомпилированы из кода, поэтому вам нужно добавить обе стены в случае, если кто-то будет выброшен компилятором.