Les assertions sont utiles pour vous informer de l'état interne du programme . Par exemple, vos structures de données ont un état valide, par exemple, une Time
structure de données ne tiendra pas la valeur de 25:61:61
. Les conditions vérifiées par les assertions sont les suivantes:
Conditions préalables, qui assurent que l'appelant respecte son contrat,
Postconditions, qui assure que l'appelé respecte son contrat, et
Les invariants, qui assurent que la structure de données contient toujours une propriété après le retour de la fonction. Un invariant est une condition qui est une condition préalable et une condition ultérieure.
Les tests unitaires sont utiles pour vous informer sur le comportement externe du module . Vous Stack
pouvez avoir un état cohérent après l' push()
appel de la méthode, mais si la taille de la pile n'augmente pas de trois après l'appel de trois fois, il s'agit d'une erreur. (Par exemple, le cas trivial où l' push()
implémentation incorrecte vérifie uniquement les assertions et se termine.)
Strictement parlant, la principale différence entre les assertions et les tests unitaires réside dans le fait que les tests unitaires contiennent des données de test (valeurs permettant au programme de s'exécuter), contrairement aux assertions. Autrement dit, vous pouvez exécuter vos tests unitaires automatiquement, alors que vous ne pouvez pas en dire autant pour les assertions. Pour les besoins de cette discussion, j'ai supposé que vous parliez de l'exécution du programme dans le contexte des tests de fonction d'ordre supérieur (qui exécutent l'ensemble du programme et ne pilotent pas les modules comme les tests unitaires). Si vous ne parlez pas de tests de fonction automatisés comme moyen de "voir les entrées réelles", alors clairement l'intérêt de l'automatisation réside dans le succès des tests unitaires. Si vous en parlez dans le cadre de tests de fonctions (automatisés), reportez-vous à la section ci-dessous.
Il peut y avoir un certain chevauchement dans ce qui est testé. Par exemple, Stack
la postcondition de a peut en fait affirmer que la taille de la pile augmente de un. Mais il y a des limites à ce qui peut être fait dans cette affirmation: faut-il aussi vérifier que l'élément supérieur est ce qui vient d'être ajouté?
Pour les deux, l'objectif est d'améliorer la qualité. Pour les tests unitaires, l'objectif est de trouver des bogues. Pour les assertions, l'objectif est de faciliter le débogage en observant les états de programme non valides dès qu'ils se produisent.
Notez que ni l'une ni l'autre technique ne vérifie l'exactitude. En fait, si vous effectuez des tests unitaires dans le but de vérifier que le programme est correct, vous obtiendrez probablement un test sans intérêt qui, à votre connaissance, fonctionnera. C'est un effet psychologique: vous ferez tout ce qui est en votre pouvoir pour atteindre votre objectif. Si votre objectif est de trouver des bugs, vos activités le refléteront.
Les deux sont importants et ont leurs propres objectifs.
[Note finale sur les assertions: pour obtenir le maximum de valeur, vous devez les utiliser à tous les points critiques de votre programme, et non à quelques fonctions clés. Sinon, la source du problème d'origine aurait peut-être été masquée et difficile à détecter sans des heures de débogage.]
:-)