Делает ли модульное тестирование Debug.Assert () ненужным? - PullRequest
10 голосов
/ 04 мая 2009

Уже давно я готов Макконнелла " Code Complete ". Теперь я снова читаю это в Hunt & Thomas ' Прагматичный программист": используйте утверждения! Примечание: не утверждения модульного тестирования, я имею в виду Debug.Assert().

После вопросов SO Когда мне следует использовать Debug.Assert ()? и Когда использовать утверждение над исключениями в классах домена утверждения полезны для разработки, поскольку "невозможные" ситуации можно найти довольно быстро. И кажется, что они обычно используются. Насколько я понял утверждения, в C # они часто используются для проверки входных переменных на «невозможные» значения.

Чтобы сделать модульные тесты краткими и максимально изолированными, я делаю классы и методы подачи с помощью null s и "невозможного" фиктивного ввода (например, пустой строки).

Такие тесты явно документируют, что они не полагаются на какой-то конкретный ввод. Примечание: я практикую то, что Мешарош "Тестовые шаблоны xUnit" описывает как Минимальное приспособление .

И в этом суть: если бы у меня были утверждения, защищающие эти входы, они взорвали бы мои юнит-тесты.

Мне нравится идея Ассертивного Программирования, но, с другой стороны, мне не нужно ее форсировать. В настоящее время я не могу думать о каком-либо использовании для Debug.Assert(). Может быть, я что-то пропустил? Есть ли у вас предложения, где они могут быть действительно полезными? Может быть, я просто переоцениваю полезность утверждений? Или, может быть, необходимо пересмотреть мой способ тестирования?

Редактировать: Рекомендации по отладке утверждений во время модульного тестирования очень похожи, но не отвечают на вопрос, который меня беспокоит: следует ли мне беспокоиться о Debug.Assert() в C #, если я тестирую, как я описал ? Если да, в какой ситуации они действительно полезны? В моей нынешней точке зрения такие юнит-тесты сделали бы Debug.Assert() ненужным.

Еще один момент: если вы действительно так думаете, это дублирующий вопрос, просто оставьте комментарий.

Ответы [ 5 ]

5 голосов
/ 05 мая 2009

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

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

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

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

4 голосов
/ 05 мая 2009

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

IMO входы в надежный API должны быть защищены проверками, которые остаются на месте независимо от типа сборки. Например, если открытый метод ожидает аргумент, представляющий собой число в диапазоне от 5 до 500, он должен быть защищен с помощью ArgumentOutOfRangeException. Сбой быстро и неудача часто с использованием исключений, насколько я понимаю, особенно когда аргумент выдвигается куда-то и используется гораздо позже.

Однако в местах, где внутреннее, переходное состояние проверяется на работоспособность (например, проверяется, что некоторое промежуточное состояние находится в разумных пределах во время цикла), кажется, что Debug.Assert больше дома. Что еще вы должны делать, если ваш алгоритм работает неправильно, несмотря на то, что ему переданы действительные аргументы? Бросить EpicFailException? :) Я думаю, что именно здесь Debug.Assert все еще полезен.

Я все еще не определился с лучшим балансом между ними. Я перестал использовать Debug.Asserts в C # с тех пор, как начал модульное тестирование, но для них все еще есть место для IMO. Я, конечно, не буду использовать их для проверки правильности использования API, но проверка работоспособности в труднодоступных местах? Конечно.

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

3 голосов
/ 05 мая 2009

Я использую как модульное тестирование, так и утверждения для разных целей.

Модульное тестирование - это автоматический эксперимент, показывающий, что ваша программа (и ее части) функционируют так, как указано. Как и в математике, экспериментирование не является доказательством, если вы не можете попробовать все возможные комбинации входных данных. Ничто не демонстрирует это лучше, чем тот факт, что даже при модульном тестировании ваш код будет иметь ошибки. Не много, но оно будет у них.

Утверждения предназначены для ловли хитрых ситуаций во время выполнения, которые обычно не должны происходить. Возможно, вы слышали о предусловиях, постусловиях, неизменяемых циклах и тому подобном. В реальном мире мы не часто проходим формальный процесс фактического доказательства (формальной логикой) того, что фрагмент кода выдает указанные постусловия, если они выполнены. Это было бы реальным математическим доказательством, но у нас часто нет времени делать это для каждого метода. Однако, проверяя, выполняются ли предварительные и постусловия, мы можем обнаружить проблемы на более ранней стадии.

2 голосов
/ 05 мая 2009

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

1 голос
/ 05 мая 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...