Assertions en Java Introduction
Transcription
Assertions en Java Introduction
Assertions en Java © Philippe GENOUD Février 2004 UJF 1 Introduction Instruction assert permet de tester des suppositions sur le comportement du code Java contient une expression booléenne supposée être toujours vraie A l’exécution par défaut les assertions ne sont pas activées, instruction sans effet possibilité de les activer pour débogage et test – Évaluation de l’expression booléenne – Si vraie, assert est sans effet – Si fausse une erreur est lancée. Intérêt Moyen rapide et efficace de détecter les erreurs de programmation Permet d’augmenter la confiance dans le code produit Facilite la maintenance du code en documentant le fonctionnement interne du programme Les assertions ont été introduites dans la version 1.4 de java Elles ne peuvent être utilisées avec les versions précédentes du langage © Philippe GENOUD UJF Février 2004 2 1 Syntaxe Dans sa forme la plus simple une assertion s’écrit : assert expression1; où expression1 est une expression booléenne A l’exécution : expression1 est évaluée, si elle est fausse une erreur de type AssertionError est lancée cet objet AssertionError ne contient pas de message © Philippe GENOUD UJF Février 2004 Object Throwable Error AssertionError 3 Syntaxe Dans sa forme plus élaborée une assertion s’écrit : assert expression1 : expression2 ; où expression1 est une expression booléenne expression2 est une expression quelconque (qui a une valeur, ce ne peut être un appel de méthode déclarée void) A l’exécution : expression1 est évaluée, si elle est fausse une erreur de type AssertionError est lancée, la valeur de expression2 (transformée en chaîne de caractères) est utilisée comme message dans l’objet AssertionError © Philippe GENOUD UJF Février 2004 4 2 Compilation/Activation Par défaut le compilateur ne reconnaît pas l’instruction assert Avant version 1.4, assert n’était pas un mot réservé, assert a pu être utilisé comme identificateur. Pour compiler du code java utilisant les assertions javac –source 1.4 MaClasseAvecAssertions.java Dans les futures versions de Java, il se peut que assert soit reconnue par défaut Ne plus utiliser dès à présent assert comme identificateur Par défaut les assertions ne sont pas testées à l’exécution Les prédicats définis par les instructions assert étant supposés être toujours vrais, il serait inefficace de les tester à chaque exécution Elles peuvent être activées à tout moment pour tester du code, diagnostiquer des erreurs, débuguer © Philippe GENOUD UJF Février 2004 5 Activation flags -ea (ou -eanableassertions) et -da (ou –disableassertions) permettent de contrôler l’activation des assertions avec différents niveaux de granularité sans argument dans toutes les classes sauf les classes système packageName... dans un package et ses sous packages ... dans le package sans nom dans le répertoire courant className dans une classe java –ea helix... –da helix.modules.carto... –da helix.types.Genome CartoUI helix modules aligment carto types pm Genome.class Les flags –esa (ou –enablesystemassertions) et –desa (ou –disablesystemassertions) permettent d’activer ou désactiver les assertions pour les classes système. CartoUI.class © Philippe GENOUD UJF Février 2004 6 3 Utilisation Les exemples qui suivent sont issus de Thinking In Java, 4th Edition, de D. Flanagan, O’Reilly Edition Pour documenter toutes les suppositions faites quand vous programmez Écriture d’une méthode manipulant une variable x dont on sait qu’elle vaut soit 0, soit 1 avant les assertions if (x == 0) { ... else { // x vaut 1 ... } avec les assertions if (x == 0) { ... else { assert x == 1 : x; // x doit valoir 1 ... } Assertion formelle Assertion informelle si le code est modifié ultérieurement et que x prend une valeur autre que 0 ou 1 lancement d’une AssertionError le bug apparaît immédiatement et est immédiatement localisé. possibilités de bugs n’apparaissant pas immédiatement et difficiles à localiser. © Philippe GENOUD Février 2004 UJF 7 Utilisation Pour tester une précondition d’une méthode privée private static Object[] subArray(Object[]a, int x, int y) { // précondition x doit être <= à y assert x <= y : "subArray: x > y"; ... } Le programmeur fait la supposition que toutes les méthodes qui invoquent cette méthode respectent cette précondition Cette supposition est possible car la méthode étant privée, il a le contrôle sur tous ses appels Il peut vérifier que cette supposition est juste en activant les assertions Ne pas utiliser assert pour tester les préconditions d’une méthode publique Le programmeur de la méthode ne peut garantir à l’avance que la méthode sera toujours appelée correctement Les arguments doivent être testés explicitement © Philippe GENOUD UJF Février 2004 8 4 Utilisation Pour tester un invariant de classe Écriture d’une classe représentant une liste d’objets, autorisant l’insertion et la suppression d’objets mais conservant toujours la liste triée. public void insert(Object o) { // effectue l’insertion ... assert isSorted(); // l’invariant de classe } Méthode testant si la liste est triée ou non © Philippe GENOUD UJF Février 2004 9 Utilisation Ce qu’il ne faut pas faire écrire des assertions utilisant des expressions avec effet de bord le comportement du programme pourra être différent selon que les assertions sont activées ou non essayer « d’attraper » (« catcher ») une AssertionError une des suppositions faites par le programmeur a été violée le code est utilisée en dehors des cas prévus, on ne peut attendre qu’il fonctionne correctement il n’y a pas de moyen plausible de récupérer ce type d’erreur "Using assertions" de Glen McCluskey, Java Developer Connection (9 avril 2002) http://java.sun.com/developer/JDCTechTips/2002/tt0409.html#tip1 © Philippe GENOUD UJF Février 2004 10 5