Утверждения полезны для того, чтобы рассказать вам о внутреннем состоянии программы . Например, что ваши структуры данных имеют допустимое состояние, например, что Time
структура данных не будет содержать значение 25:61:61
. Проверенные утверждениями условия:
Предпосылки, которые гарантируют, что звонящий соблюдает свой контракт,
Постусловия, которые гарантируют, что вызываемый абонент сохраняет свой контракт, и
Инварианты, которые гарантируют, что структура данных всегда имеет некоторое свойство после возврата из функции. Инвариант - это условие, которое является предварительным условием и постусловием.
Модульные тесты полезны для того, чтобы рассказать вам о внешнем поведении модуля . У вас Stack
может быть непротиворечивое состояние после вызова push()
метода, но если размер стека не увеличивается в три раза после его вызова три раза, то это ошибка. (Например, тривиальный случай, когда неправильная push()
реализация только проверяет утверждения и выходы.)
Строго говоря, основное различие между утверждениями и модульными тестами заключается в том, что модульные тесты имеют тестовые данные (значения, которые нужно запустить программе), а утверждения - нет. То есть вы можете выполнять свои модульные тесты автоматически, в то время как вы не можете сказать то же самое для утверждений. Ради этого обсуждения я предположил, что вы говорите о выполнении программы в контексте функциональных тестов высшего порядка (которые выполняют всю программу, а не управляют модулями, такими как модульные тесты). Если вы не говорите об автоматизированных функциональных тестах как о способе «увидеть реальные входные данные», тогда ясно, что ценность заключается в автоматизации, и, таким образом, выигрывают модульные тесты. Если вы говорите об этом в контексте (автоматических) функциональных тестов, то смотрите ниже.
Там может быть некоторое совпадение в том, что тестируется. Например, Stack
постусловие может фактически утверждать, что размер стека увеличивается на единицу. Но есть пределы тому, что может быть выполнено в этом утверждении: следует ли также проверять, что верхний элемент - это то, что было только что добавлено?
Для обоих целью является повышение качества. Цель модульного тестирования - найти ошибки. Для утверждений цель состоит в том, чтобы упростить отладку, наблюдая недействительные состояния программы, как только они возникают.
Обратите внимание, что ни один из методов не проверяет правильность. Фактически, если вы проводите модульное тестирование с целью проверки правильности программы, вы, скорее всего, получите неинтересный тест, который, как вы знаете, будет работать. Это психологический эффект: вы будете делать все, чтобы достичь своей цели. Если ваша цель - найти ошибки, ваша деятельность будет отражать это.
Оба важны, и имеют свои собственные цели.
[В качестве заключительного замечания об утверждениях: чтобы получить наибольшее значение, вам нужно использовать их во всех критических точках вашей программы, а не в нескольких ключевых функциях. В противном случае первоначальный источник проблемы мог бы быть замаскирован и его трудно обнаружить без нескольких часов отладки.]
:-)