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