J'ai récemment rencontré du code nouvellement écrit qui était entrecoupé de beaucoup de Debug.Assert (C #).
Devrions-nous encore l'utiliser largement malgré l'utilisation du TDD, du BDD et des tests unitaires en général?
J'ai récemment rencontré du code nouvellement écrit qui était entrecoupé de beaucoup de Debug.Assert (C #).
Devrions-nous encore l'utiliser largement malgré l'utilisation du TDD, du BDD et des tests unitaires en général?
Réponses:
Je ne vois aucune raison pour laquelle vous ne devriez pas utiliser Assert. Ce faisant, vous avez déjà reconnu le besoin de gardes, comme les conditions préalables et les invariants, et vous vous dirigez vers la conception par contrat . L'affirmation n'est qu'un moyen d'y parvenir ...
// 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);
}
Ce sont toutes des façons de réaliser la même chose: la robustesse du code. Il s'agit simplement de choisir une option, dont Assert est un choix valide.
Notez que je n'ai pas du tout mentionné de tests unitaires jusqu'à présent, car ils accomplissent quelque chose de très différent. Un test unitaire prouve formellement la robustesse du code en exerçant une garde:
[Test]
void SomeMethod_WhenGivenNull_ThrowsArgumentNullException()
{
delegate call = () => someObject.SomeMethod(null);
Assert.That(call).Throws<ArgumentNullException>();
}
Il s'agit d'un type d'affirmation entièrement différent ...
** Notez que dans certains frameworks, il est en fait assez difficile de tester unitaire pour un échec d'assertion, car un échec d'assertion peut faire baisser le temps d'exécution, donc l'une des autres options peut être préférée ... *
Je considère les assertions et les tests unitaires comme deux outils différents dans ma boîte à outils. Certaines choses sont mieux adaptées à l'une, et certaines sont mieux adaptées à l'autre.
À titre d'exemple, ces jours-ci, j'utilise principalement des assertions pour valider les paramètres des méthodes non publiques.
Je considère Debug.Assert comme une optimisation prématurée de nos jours. Sauf si vous avez vraiment besoin des performances, la suppression de l'assertion en mode de publication peut masquer les bogues plus longtemps.
Comme MattDavey le fait remarquer , les contrats de code peuvent être supérieurs, fournissant une vérification statique au lieu d'une vérification dynamique, et s'ils ne sont pas disponibles, je préférerais Trace.Assert ou un simple ancienif(x) throw SomeException;
Debug
classe ... donc la suppression d'appels à Assert
simplement pour des performances n'est pas seulement une optimisation prématurée, c'est un non-sens.