C # - Que fait la méthode Assert ()? Est-ce toujours utile?

156

Je débogue avec des points d'arrêt et je réalise l'appel d'assert? Je pensais que c'était uniquement pour les tests unitaires. Que fait-il plus que le point d'arrêt? Puisque je peux breakpoint, pourquoi devrais-je utiliser Assert?

Pokus
la source
9
Au fait, si vous êtes intéressé par les assertions, vous devez absolument vous plonger dans les contrats de code .
MasterMastic
Copie

Réponses:

200

Dans une compilation de débogage, Assertprend une condition booléenne comme paramètre et affiche la boîte de dialogue d'erreur si la condition est fausse. Le programme se poursuit sans interruption si la condition est vraie.

Si vous compilez dans Release, tous Debug.Assertsont automatiquement omis.

Patrick Desjardins
la source
12
comment puis-je obtenir le même comportement de Debug.Assert en mode Release?
Hamish Grubijan
15
Trace.Assert pour le mode de publication réfs apparemment: msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/e63efys0.aspx
Tim Abell
8
@HamishGrubijan Et pourquoi voudriez-vous Debug.Asserten mode sortie?
Camilo Martin
25
OMI, omettre les assertions du code de libération, c'est comme mener des exercices de sauvetage à quai, puis laisser les bateaux de sauvetage derrière lorsque vous naviguez. :)
Chrisd
113
Les assertions ne sont pas un canot de sauvetage, mais un système de détection d'icebergs. Puisque l'utilisateur ne dirige pas le vaisseau, une affirmation dans le code de version leur dit simplement qu'ils sont condamnés; cela ne leur permet pas d'éviter l'iceberg.
Stefan
97

À partir du code terminé

8 Programmation défensive

8.2 Assertions

Une assertion est un code utilisé pendant le développement - généralement une routine ou une macro - qui permet à un programme de se vérifier pendant son exécution. Lorsqu'une assertion est vraie, cela signifie que tout fonctionne comme prévu. Quand il est faux, cela signifie qu'il a détecté une erreur inattendue dans le code. Par exemple, si le système suppose qu'un fichier d'informations client ne contiendra jamais plus de 50 000 enregistrements, le programme peut contenir une assertion selon laquelle le nombre d'enregistrements est inférieur ou égal à 50 000. Tant que le nombre d'enregistrements est inférieur ou égal à 50 000, l'assertion restera silencieuse. S'il rencontre plus de 50 000 enregistrements, cependant, il «affirmera» bruyamment qu'il y a une erreur dans le programme.

Les assertions sont particulièrement utiles dans les programmes volumineux et complexes et dans les programmes à haute fiabilité. Ils permettent aux programmeurs d'éliminer plus rapidement les hypothèses d'interface non concordantes, les erreurs qui s'infiltrent lorsque le code est modifié, etc.

Une assertion prend généralement deux arguments: une expression booléenne qui décrit l'hypothèse supposée être vraie et un message à afficher si ce n'est pas le cas.

(…)

Normalement, vous ne voulez pas que les utilisateurs voient les messages d'assertion dans le code de production; les affirmations sont principalement destinées à être utilisées pendant le développement et la maintenance. Les assertions sont normalement compilées dans le code au moment du développement et compilées hors du code pour la production. Pendant le développement, les assertions éliminent les hypothèses contradictoires, les conditions inattendues, les mauvaises valeurs transmises aux routines, etc. Pendant la production, elles sont compilées hors du code afin que les assertions ne dégradent pas les performances du système.

Juan
la source
2
Le livre, Writing Solid Code, a également une grande discussion sur l'utilisation d'assert. Ils sont un excellent outil de débogage!
zooropa
39

Vous devriez l'utiliser lorsque vous ne voulez pas avoir à interrompre chaque petite ligne de code pour vérifier les variables, mais que vous voulez obtenir une sorte de retour si certaines situations sont présentes, par exemple:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");
thelsdj
la source
Si j'ajoute une ligne de code similaire au vôtre ci-dessus, l'exécution de mon programme donne l'erreur suivante: "erreur CS0103: Le nom 'Debug' n'existe pas dans le contexte actuel". Ai-je besoin d'une sorte de déclaration d'utilisation pour que cela fonctionne?
Josh Desmond
4
@JoshDesmondSystem.Diagnostics
Sinjai
16

Assert vous donne également une autre occasion de rire des compétences de conception d'interface utilisateur de Microsoft. Je veux dire: une boîte de dialogue avec trois boutons Abandonner, Réessayer, Ignorer et une explication sur la façon de les interpréter dans la barre de titre!

Joe
la source
3
Abandonner / réessayer / ignorer est classique! Était-ce des affirmations qui provoquaient l'affichage permanent de Windows 3.1?
devlord
Fondamentalement, c'est parce qu'il utilise un MessageBox, qui, comme vous le dites, remonte à Windows 3.1 et n'a que des étiquettes de bouton prédéfinies. Vous pouvez donc comprendre pourquoi le hack a eu lieu, mais pas pourquoi il est toujours là en 2008!
Joe
4
@Joe C'est quelque chose qui ne devrait être vu que par les développeurs et non par les utilisateurs finaux, donc sa mise à jour est probablement un élément de priorité extrêmement faible. Si cela vous dérange, vous pouvez modifier les collections Debug.Listeners ou Trace.Listeners pour remplacer le gestionnaire par défaut par celui qui fait tout ce que vous voulez.
Dan Is Fiddling By Firelight
5
Et bien c'est 2019 maintenant et la même boîte de dialogue / boutons sont toujours là!
Bouke
10

Assert vous permet d'affirmer qu'une condition (post ou pré) s'applique dans votre code. C'est une façon de documenter vos intentions et de demander au débogueur de vous informer par un dialogue si votre intention n'est pas satisfaite.

Contrairement à un point d'arrêt, l'Assert accompagne votre code et peut être utilisé pour ajouter des détails supplémentaires sur votre intention.

Jeff Yates
la source
10

Assert peut vous aider à donner un comportement de messagerie séparé entre le test et la publication. Par exemple,

Debug.Assert(x > 2)

ne déclenchera une pause que si vous exécutez une version de «débogage», pas une version de version. Il y a un exemple complet de ce comportement ici

Ryan
la source
10

Tout d'abord, la Assert()méthode est disponible pour les classes Traceet Debug.
Debug.Assert()s'exécute uniquement en mode débogage.
Trace.Assert()s'exécute en mode Debug and Release.

Voici un exemple:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Exécutez ce code en mode débogage, puis en mode Release.

entrez la description de l'image ici

Vous remarquerez qu'en mode débogage, votre Debug.Assertinstruction de code échoue, vous obtenez une boîte de message indiquant la trace de pile actuelle de l'application. Cela ne se produit pas en mode Release car la Trace.Assert()condition est vraie (i == 4).

WriteLine() La méthode vous donne simplement la possibilité de consigner les informations dans la sortie Visual Studio. entrez la description de l'image ici

Serge Volochenko
la source
5

Les affirmations occupent une place importante dans la conception par contrat (DbC) qui, si je comprends bien, a été introduite / approuvée par Meyer, Bertand. 1997. Construction logicielle orientée objet.

Une caractéristique importante est qu'ils ne doivent pas produire d'effets secondaires, par exemple vous pouvez gérer une exception ou prendre une autre ligne de conduite avec une instruction if (programmation défensive).

Les affirmations sont utilisées pour vérifier les conditions préalables / postérieures au contrat, la relation client / fournisseur - le client doit s'assurer que les conditions préalables du fournisseur sont remplies, par exemple. envoie 5 £ et le fournisseur doit s'assurer que les post-conditions sont remplies, par exemple. livre 12 roses. (Juste une simple explication du client / fournisseur - peut accepter moins et livrer plus, mais sur les assertions). C # introduit également Trace.Assert (), qui peut être utilisé pour le code de version.

Pour répondre à la question oui, ils sont toujours utiles, mais peuvent ajouter de la complexité + la lisibilité du code et du temps + difficile à maintenir. Devrions-nous encore les utiliser? Oui, allons-nous tous les utiliser? Probablement pas, ou pas dans la mesure de ce que décrit Meyer.

(Même le cours OU Java sur lequel j'ai appris cette technique ne montrait que des exemples simples et le reste du code n'appliquait pas les règles d'assertion DbC sur la plupart du code, mais était supposé être utilisé pour assurer l'exactitude du programme!)

Knightlore
la source
3

La façon dont j'y pense est Debug.Assert est un moyen d'établir un contrat sur la façon dont une méthode est censée être appelée, en se concentrant sur des détails sur les valeurs d'un paramètre (au lieu de simplement le type). Par exemple, si vous n'êtes pas censé envoyer une valeur null dans le deuxième paramètre, vous ajoutez l'Assert autour de ce paramètre pour dire au consommateur de ne pas le faire.

Cela empêche quelqu'un d'utiliser votre code de manière stupide. Mais cela permet également à cette manière stupide de passer à la production et de ne pas donner le mauvais message à un client (en supposant que vous construisiez une version Release).

Flory
la source
6
Il est important de souligner, cependant, que les paramètres invalides sur les méthodes publiques doivent lever des exceptions d'argument. Seules les méthodes privées doivent valider l'entrée avec des assertions. Les valeurs qui viennent de l'extérieur sont toujours suspectes!
Jeffrey L Whitledge