Недавно я натолкнулся на какой-то недавно написанный код, в который было добавлено множество Debug.Assert (C #).
Должны ли мы все еще использовать это широко, несмотря на использование TDD, BDD и модульного тестирования в целом?
Недавно я натолкнулся на какой-то недавно написанный код, в который было добавлено множество Debug.Assert (C #).
Должны ли мы все еще использовать это широко, несмотря на использование TDD, BDD и модульного тестирования в целом?
Ответы:
Я не вижу причин, почему вы не должны использовать Assert. Тем самым вы уже признали необходимость в защитниках, таких как предварительные условия и инварианты, и делаете шаг к Проектированию по контракту . Утверждать это только один из способов достижения этого ...
// Precondition using Asert
void SomeMethod(Foo someParameter)
{
Debug.Assert(someParameter != null)
}
// Precondition using If-Then-Throw
void SomeMethod(Foo someParameter)
{
if (someParameter == null)
throw new ArgumentNullException("someParameter");
}
// Precondition using Code Contracts
void SomeMethod(Foo someParameter)
{
Contract.Requires(someParameter != null);
}
// Precondition using some custom library
void SomeMethod(Foo someParameter)
{
Require.ArgumentNotNull(() => someParameter);
}
Все это способы достижения одного и того же: надежность в коде. Это просто сводится к выбору опции, из которых Assert является правильным выбором.
Обратите внимание, что я пока не упомянул юнит-тесты, поскольку они выполняют нечто совершенно иное. Модульный тест формально подтверждает надежность кода, применяя защиту:
[Test]
void SomeMethod_WhenGivenNull_ThrowsArgumentNullException()
{
delegate call = () => someObject.SomeMethod(null);
Assert.That(call).Throws<ArgumentNullException>();
}
Это совершенно другой вид утверждения ...
** Обратите внимание, что в некоторых средах на самом деле довольно сложно выполнить модульное тестирование для ошибки подтверждения, так как ошибка подтверждения может привести к снижению времени выполнения, поэтому один из других вариантов может быть предпочтительным ... *
Я считаю, что утверждения и модульные тесты - это два разных инструмента в моей панели инструментов. Некоторые вещи лучше подходят для одного, а некоторые лучше подходят для другого.
Например, в настоящее время я в основном использую утверждения для проверки параметров для закрытых методов.
В настоящее время я считаю Debug.Assert преждевременной оптимизацией. Если вам действительно не нужна производительность, подавление Assert в режиме выпуска может скрывать ошибки дольше.
Как указывает MattDavey, кодовые контракты могут быть лучше, обеспечивая статическую проверку вместо динамической проверки, и, если она недоступна, я бы предпочел Trace.Assert или просто старыйif(x) throw SomeException;
Debug
класса будут пропущены из компиляции ... поэтому подавление вызовов Assert
просто для производительности - это не просто преждевременная оптимизация, это просто бессмыслица.