1 Complément JAVA les assertions
2 lan Tests et erreurs Assertions en Java Utilisation Bonne pratique des assertions
3 Erreurs dans une application Au cours d’un développement, on est jamais sur de ne pas faire d’erreur Les erreurs à l’exécution peuvent conduire à –La levée d’ exceptions corrigées « facilement » –Ou... 1
4 Erreurs dans une application Au cours d’un développement, on est jamais sur de ne pas faire d’erreur Les erreurs à l’exécution peuvent conduire à –La levée d’exceptions corrigées « facilement » –Ou... des résultats erronés Développement d’une application –Phase de tests et de validation –Déploiement réel On ne vérifie jamais assez !! Danger 1
5 Erreurs dans une application Au cours d’un développement, on est jamais sur de ne pas faire d’erreur Les erreurs à l’exécution peuvent conduire à –La levée d’exceptions corrigées « facilement » –Ou... des résultats erronés Développement d’une application –Phase de tests et de validation –Déploiement réel On ne vérifie jamais assez !! Danger 1
6 Coût de vérification 1 Compromis entre –La sûreté du code –Le temps consacré au test (coût de développement) Distinguer différents types d'erreurs –Erreurs qui pourraient se produire à l’exécution A cause de l’utilisateur A cause d’une mauvaise configuration A cause d'un évènement extérieur (connection réseau, etc...) –Erreurs qui sont censées ne jamais se produire Effets de bords non prévus Remettent en cause toute l’application Ces cas seront traités différemment
7 Erreurs générées par l'utilisateur Exemple: –L’utilisateur rentre une valeur négative pour un nb de jours Caractéristiques –Ces erreurs peuvent arriver fréquemment –Non liées "au code" mais prévisibles –Ne doivent pas conduire à la fin de l'application Y consacrer du temps pour une interface robuste –Cas exceptionnels mais possibles gérer avec des exceptions 1 Vous savez faire
8 Exception (rappel) Un bloc try, un bloc catch –On récupère les BONNES exceptions 1 try { // code // throws } catch (... ) { //code }
9 Erreurs de codage Exemple –L'indice d'accès à un tableau ne correspond à aucun élément alors que le concepteur pense avoir tout fait pour Caractéristiques –Jamais en théorie –Du à un mauvais codage –Peuvent conduire à des résultats incertains (car non prévus) Comme elles sont (censées) ne pas arriver –Peu de temps à y consacrer assertions 1 Contenu de ce cours
10 Assertions Principe : –"plutôt deux fois qu'une" –Il vaut mieux vérifier son code au cours de l'exécution même si tout doit bien se passer Définition: –"Proposition que l'on avance comme vraie" Caractéristique: –Un ensemble de conditions qui seront testées et qui doivent être vraies dans le cas du bon déroulement d'un programme –Ce que le concepteur du code sait être vrai, si … on lui accorde une confiance totale … 1
11 PARADOXEs ? PARADOXE : –on traite des évènements qui sont censés ne pas arriver Simplement –On sait qu'il y a toujours des erreurs –Mieux vaut s’en rendre compte que pas du tout –On les gère à moindre cout 1
12 PARADOXEs ? PARADOXE : –on traite des évènements qui sont censés ne pas arriver Simplement –On sait qu'il y a toujours des erreurs –Mieux vaut s’en rendre compte que pas du tout –On les gère à moindre coût Question : –A quel moment faut-il en mettre ? –Quand on y pense ! Attention à vos tests –les mauvais codeurs font les mauvais tests Soigner vos tests !!! 1
13 PARADOXEs ? PARADOXE : –on traite des évènements qui sont censés ne pas arriver Simplement –On sait qu'il y a toujours des erreurs –Mieux vaut s’en rendre compte que pas du tout –On les gère à moindre coût Question : –A quel moment faut-il en mettre ? –Quand on y pense ! Attention à vos tests –les mauvais codeurs font les mauvais tests Soigner vos tests !!! 1
14 Quelques exemples L'indice d'accès à un tableau est inférieur à la taille du tableau et supérieur à 0. Après ajout d'un élément dans une pile, cet élément se retrouve en tête de la pile. Domaine d'entrée d'une fonction mathématique. Le résultat d’un calcul doit se trouver dans un certain intervalle 1
15 De manière plus rigoureuse Définition –Une assertion est décrite comme "une déclaration permettant de tester des exigences vis à vis du programme" Programmation défensive –On pare aux problèmes en annonçant au sein du programme ce que l'on souhaite utiliser Conception par contrat : –Qui met en avant l'importance de contraintes spécifiées explicitement et qui doivent restées vraies une fois le programme lancé 1
16 Plan Tests et erreurs Assertions en Java Utilisation Bonne pratique des assertions
17 Mise en place Existent depuis Java 1.4 Outils –Mot clef assert –Classe AssertionError extends Thorwable –Méthodes au sein de ClassLoader 2
18 Mise en place Existent depuis Java 1.4 Outils –Mot clef assert –Classe AssertionError extends Thorwable –Méthodes au sein de ClassLoader 2
19 "assert condition : message" –Condition : condition à respecter –Message : message envoyé au gestionnaire d'assertion Exemple classe bidouille Mot clef assert public class bidouille { public void violette (int x) { assert x>0; //ou bien Assert x>0: « x doit être supérieur à 0 »; System.out.println("x"); } public static void main( String[] args ) { Bidouille bidouille = new Bidouille(); bidouille.violette(1); } 2
20 Fonctionnement Dés qu’une assertion est rencontrée Elle est testée –Si elle est vérifiée, on passe à la suite –Sinon, une AssertionError est envoyée –puisque hérite de Throwable Le gestionnaire d’assertion la récupère Il est donc possible de faire un catch –Mais c'est à éviter 2
21 Équivalence 2 public class aClass { public void aMethod( int argument ) { Object o = null; //... Cree un objet o assert o != null : "Can't get a Foo,argument="+argument; } public class aClass { public void aMethod( int argument ) { Object o = null; //... Cree un objet o if (!(o != null)) { throw new AssertionError( "Can't get a o, argument="+argument ); }
22 Mise en oeuvre réelle Les assertions restent à tout moment dans le code Elles sont débrayables à l’exécution Mettre les assertions (phase de test) –Java –ea Enlever les assertions (phase de deploiement) –Java –da 2
23 2 public class bidouille { public void violette (int x) { assert x>0; //ou bien Assert x>0: « x doit être supérieur à 0 »; System.out.println("x"); } public static void main( String[] args ) { Bidouille bidouille = new Bidouille(); bidouille.violette(1); } Compilation –javac bidouille.java Exécution –java bidouille ? –java –ea bidouille
24 2 public class bidouille { public void violette (int x) { assert x>0; //ou bien Assert x>0: « x doit être supérieur à 0 »; System.out.println("x"); } public static void main( String[] args ) { Bidouille bidouille = new Bidouille(); bidouille.violette(1); } Compilation –javac bidouille.java Exécution –java bidouille –java –ea bidouille 1
25 Compilation –javac bidouille.java Exécution –java bidouille ? –java –ea bidouille 2 public class bidouille { public void violette (int x) { assert x>0; //ou bien Assert x>0: « x doit être supérieur à 0 »; System.out.println("x"); } public static void main( String[] args ) { Bidouille bidouille = new Bidouille(); bidouille.violette(-1); }
26 Compilation –javac bidouille.java Exécution –java bidouille –java –ea bidouille 2 public class bidouille { public void violette (int x) { assert x>0; //ou bien Assert x>0: « x doit être supérieur à 0 »; System.out.println("x"); } public static void main( String[] args ) { Bidouille bidouille = new Bidouille(); bidouille.violette(-1); }
27 Compilation –javac bidouille.java Exécution –java bidouille –java –ea bidouille 2 public class bidouille { public void violette (int x) { assert x>0; //ou bien Assert x>0: « x doit être supérieur à 0 »; System.out.println("x"); } public static void main( String[] args ) { Bidouille bidouille = new Bidouille(); bidouille.violette(-1); } Exception in thread "main" java.lang.AssertionError: x doit sup à 0 at Bidouille.violette(Bidouille.java:5) at Bidouille.main(Bidouille.java:11)
28 Exemple (bis) Que fait le programme suivant ? Comment fonctionne-t-il ? A quoi sert-il ? public class verifie { public static void main (String[] args) { assert false : "oui"; System.out.println("non"); } 2
29 Exemple (bis) Ou encore public class verifie { public static void main (String[] args) { try { assert false : "oui"; System.out.println("non"); } catch(AssertionError e) { System.out.println("oui"); } 2
30 Plan Tests et erreurs Assertions en Java Utilisation Bonne pratique des assertions
31 Utilisation pratique Cela ne remplace pas les Exceptions !!! Programmation par contrat –"paradigme de programmation dans lequel le déroulement des traitements est régi par des règles" (wikipedia) Plusieurs type d'assertions –Pre-conditions –Post-conditions –Invariants Invariants logiques Invariant du contrôle des flux invariants fonctionnels 3
32 Pre-condition Définition – Condition nécessaire au bon fonctionnement du code de la méthode Utilisation – Assertion au début de la méthode Exemple – pour rechercher un élément dans un tableau supposé non vide, il faut qu’il le soit effectivement Attention, il ne s'agit pas forcément de vérifier les paramètres passés à la méthode 3 Si la méthode est publique, c'est des exceptions !!
33 Post-condition Définition –Condition sur l’état du système tel qu’il est laissé à la fin de l’appel de la méthode Utilisation –Assertion à la fin de la méthode Exemple –lorsqu’on ajoute un objet dans une pile, il se trouve en tête de pile. 3
34 Invariant Définition –Condition qui est toujours vérifiée au cours du programme Trois types d'invariants –Invariant fonctionnel –Invariants logiques –Invariants de contrôle des flux 3
35 Invariant fonctionnel Définition –Contraintes que doivent respecter les instances d’une classe Utilisation –Assertion quand des attributs concernés peuvent être modifiés Exemple –La largeur et hauteur d’un objet rectangle sont positifs –Une voiture a toujours 4 roues 3
36 Invariants logiques Définition –Invariants pour lesquels la logique sémantique du code mène à ce qui semble être une tautologie au moment ou on l’écrit mais qui pourrait fort bien être détruit par une modification future du code Utilisation –Assertion lorsqu'une partie du code implique des vérités non explicites Exemple –Coef = x *x / (1+x*x), Coef entre 0 et 1 (jamais écrit explicitement) –Le rapport longueur sur périmètre est compris entre 0 et 1 3
37 Invariant de contrôle des flux Définition –Invariant qui concernent le déroulement de l'exécution du programme (points de passage interdits, ou passage uniquement avec certaines conditions,...) Utilisation –Assertions dans des endroits où il est censé être impossible d'accéder Exemple –la recherche d’un élément qui doit se trouver dans le tableau doit nous retourner un indice, etc … 3
38 Contrôle des flux (ex) Exemple –Tableau T –On sait que l'élément e s'y trouve Conséquence: –La recherche de l'indice de e doit retourner une valeur 3 int i=0; while (i<T.length) { if (T[i]==e) return(i); i++; } assert false : "élément non trouve"; Point de passage interdit
39 Contrôle des flux (ex) Passage avec conditions Int indice=-1; int i=0; while (i<T.length) { if (T[i]==e) indice=i; i++; } assert indice!=-1 : "element non trouve"; return indice; Point de passage avec condition Indice != -1
40 Contrôle des flux (ex2) Exemple –Nombre de valeurs réduites pour un élément a 0,1 ou 2 3 Switch (a) { case 0:... ; break; case 1:... ; break; case 2:... ; break; default : assert false:"mauvaise valeur de a"; } Point de passage interdit
41 Plan Tests et erreurs Assertions en Java Utilisation Bonne pratique des assertions
42 Bonne pratique des assertions Différence assertions/exceptions –Exception : Vérifier des paramètres passés, événements extérieurs –Assertions : Détecter des cas qui ne devraient JAMAIS se produire Or les méthodes publiques peuvent être appelées de n’importe où avec n’importe quel paramètre Conclusion pour vérification des paramètres –Pas d’assertion pour les méthodes publiques! –Assertions pour les méthodes privées ! 4 En gros : interne assertions externe exception
43 Bonne pratique des assertions Ne pas mettre des conditions qui modifient l’état du système assert connect(): "connection échouée" Aboutit à deux problèmes – le manque de lisibilité –Mais surtout le fait que l’assertion est débrayable Et donc que le code n'est plus exécuté 4
44 Bonne pratique des assertions Attention lorsque vous faites des vérifications –Sur les réels, etc … –Assert r1=r2 Deux réels ne sont jamais vraiment égaux –Utiliser plutôt la valeur absolue de la différence –assert abs(r1-r2)<
45 Conclusion Assertions permettent d’ajouter une robustesse intrinsèque au code développé Bon compromis –Simple à mettre en place –Pour des cas très rares Attention, ce n’est pas parce qu’aucune assertion n’est violée que votre code fonctionne Reste a vérifier que le code fonctionne bien en le mettant face à des situations difficiles JUnit