Recentemente, deparei com um código recém-escrito que foi intercalado com muito Debug.Assert (C #).
Ainda devemos usar isso amplamente, apesar do uso de TDD, BDD e testes de unidade em geral?
Recentemente, deparei com um código recém-escrito que foi intercalado com muito Debug.Assert (C #).
Ainda devemos usar isso amplamente, apesar do uso de TDD, BDD e testes de unidade em geral?
Respostas:
Não vejo nenhuma razão para você não usar o Assert. Ao fazer isso, você já reconheceu a necessidade de proteções, como pré-condições e invariantes, e está fazendo uma mudança em direção ao Design por contrato . Afirmar é apenas uma maneira de conseguir isso ...
// 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);
}
Todas são maneiras de conseguir a mesma coisa: robustez no código. Tudo se resume a escolher uma opção, da qual Assert é uma opção válida.
Observe que até agora não mencionei testes de unidade, pois eles realizam algo muito diferente. Um teste de unidade prova formalmente a robustez do código exercitando uma proteção:
[Test]
void SomeMethod_WhenGivenNull_ThrowsArgumentNullException()
{
delegate call = () => someObject.SomeMethod(null);
Assert.That(call).Throws<ArgumentNullException>();
}
Este é um tipo totalmente diferente de afirmar ...
** Observe que, em algumas estruturas, é realmente muito difícil testar a unidade para uma falha de asserção, pois uma falha de asserção pode reduzir o tempo de execução inteiro, portanto, uma das outras opções pode ser preferida ... *
Considero afirmações e testes de unidade como duas ferramentas diferentes na minha caixa de ferramentas. Algumas coisas são mais adequadas para uma e outras são mais adequadas para a outra.
Como exemplo, hoje em dia eu uso principalmente declarações para validar parâmetros para métodos não públicos.
Eu vejo Debug.Assert como otimização prematura hoje em dia. A menos que você realmente precise do desempenho, suprimir o Assert no modo de liberação pode ocultar bugs por mais tempo.
Como MattDavey salienta, os contratos de código podem ser superiores, fornecendo verificação estática em vez de verificação dinâmica e, se não estiver disponível, eu preferiria o Trace.Assert ou uma planilha antiga.if(x) throw SomeException;
Debug
classe sejam ignoradas da compilação ... portanto, suprimir as chamadas Assert
simplesmente para desempenho não é apenas otimização prematura, é um absurdo.