Assertions en Java Introduction
Transcription
Assertions en Java Introduction
Assertions en Java © Philippe GENOUD Février 2004 UJF 1 Introduction l Instruction assert permet de tester des suppositions sur le comportement du code Java contient une expression booléenne supposée être toujours vraie l A l’exécution l par défaut les assertions ne sont pas activées, instruction sans effet l possibilité de les activer pour débogage et test l l – Évaluation de l’expression booléenne – Si vraie, assert est sans effet – Si fausse une erreur est lancée. l Intérêt l Moyen rapide et efficace de détecter les erreurs de programmation l Permet d’augmenter la confiance dans le code produit l 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 l Dans sa forme la plus simple une assertion s’écrit : assert expression1; où l l expression1 est une expression booléenne A l’exécution : l expression1 est évaluée, l si elle est fausse une erreur de type AssertionError est lancée l cet objet AssertionError ne contient pas de message © Philippe GENOUD UJF Février 2004 Object Throwable Error AssertionError 3 Syntaxe l Dans sa forme plus élaborée une assertion s’écrit : l assert expression1 : expression2 ; où l l 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) l A l’exécution : l expression1 est évaluée, l si elle est fausse une erreur de type AssertionError est lancée, l 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 l 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. l Pour compiler du code java utilisant les assertions l javac –source 1.4 MaClasseAvecAssertions.java l Dans les futures versions de Java, il se peut que assert soit reconnue par défaut l Ne plus utiliser dès à présent assert comme identificateur l Par défaut les assertions ne sont pas testées à l’exécution l 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 l © Philippe GENOUD UJF Février 2004 5 Activation l flags -ea (ou -eanableassertions) et -da (ou –disableassertions) permettent de contrôler l’activation des assertions avec différents niveaux de granularité l sans argument dans toutes les classes sauf les classes système l packageName... dans un package et ses sous packages l ... dans le package sans nom dans le répertoire courant l 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 l 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 l 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 l 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 l 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 l Ce qu’il ne faut pas faire l écrire des assertions utilisant des expressions avec effet de bord l le comportement du programme pourra être différent selon que les assertions sont activées ou non l 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 l il n’y a pas de moyen plausible de récupérer ce type d’erreur l l © Philippe GENOUD UJF Février 2004 10 5