US

Les assertions

Maintenant qu'on a vu comment utiliser les spécifications pour documenter des méthodes, on va s'intéresser à un autre sujet important en programmation : le débogage, c'est-à-dire retrouver les endroits dans un programme qui font que le programme ne fonctionne pas correctement.

Revoici la méthode qui permet de faire la division de deux entiers mais un peu modifiée.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
/**
* Divise deux entiers
*
* @pre b != 0
* @post La valeur renvoyée contient le quotient de a par b
*/
public int divide (int a, int b)
{
    if (b == 0) return 0;
 
    return a / b;
}
listing j7.11 La méthode divide

Cette méthode est tout à fait correcte par rapport à sa spécification, en effet, si la précondition est respectée, alors la postcondition est réalisée, à savoir que la valeur renvoyée par la méthode contient le quotient de a par b. Maintenant, si la précondition n'est pas respectée, l'utilisateur ne sait pas ce qui va se passer, avec cette implémentation de la méthode, il se trouve que la méthode va renvoyer 0.

Imaginons maintenant que quelqu'un souhaite utiliser cette méthode. Par exemple, un professeur qui veut calculer les moyennes de ses étudiants. Il va donc appeler la méthode pour chacun de ces étudiants comme le montre le listing suivant.

1 
2 
3 
4 
5 
6 
int result = 16;
int max = 20;
 
int percentage = divide (result, max) * 100;
 
System.out.println ("L'étudiant a obtenu " + percentage + "%");
listing j7.12 Utilisation de la méthode divide

L'exécution du programme va bien entendu afficher à la console :

L'étudiant a obtenu 80%

Maintenant, imaginons que les notes ne soient pas encodées directement dans une variable mais qu'on aie par exemple une interface graphique qui permette d'encoder les points des étudiants. On aurait par exemple une méthode getnote qui renvoie les points de l'étudiant. On remplacerait donc la première ligne du programme par

1 
int result = getnote()
listing j7.13 Récupérer les points d'un étudiant

Maintenant, imaginons qu'un problème se trouve dans cette méthode getnote et qu'elle renvoie 0 pour l'étudiant alors que celui-ci a fait 16. Que se passe-t'il ? On affecte la valeur 0 à la variable result, puis on appelle la méthode divide. la précondition n'est pas respectée, donc le résultat obtenu ne sera pas celui définit par la postcondition, dans notre implémentation, la méthode divide renvoie 0, et donc l'étudiant va se retrouver avec 0% alors qu'il devrait avoir 80%.

Le programme n'est donc pas correct, pourtant il compile et s'exécute sans problèmes. Le problème, c'est que le programmeur a utilisé une méthode sans s'assurer au préalable que la précondition était bien vérifiée.

L'instruction assert

Java propose une instruction assert qui permet de vérifier une assertion. Une assertion est une phrase à laquelle on peut attribuer une valeur booléenne. On va pouvoir utiliser l'instruction assert pour s'assurer que les préconditions sont bien vérifiées. La syntaxe est simple, on écrit assert suivi d'une expression booléenne.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
/**
* Divise deux entiers
*
* @pre b != 0
* @post La valeur renvoyée contient le quotient de a par b
*/
public int divide (int a, int b)
{
    assert b != 0;
 
    return a / b;
}
listing j7.14 Écrire une assertion

Avec l'instruction assert, on va donc énoncer une vérité, à savoir une expression booléenne qui doit être vraie pour que le programme puisse continuer sans soucis. Que se passe-t'il si l'assertion est fausse ? Et bien le programme s'arrête tout de suite avec un message d'erreur à la console. Si par exemple on fait l'appel divide (5, 0), le programme s'arrête avec le message d'erreur suivant

Exception in thread "main" java.lang.AssertionError
	at Test.divide(AssertionTest.java:5)
	at Test.main(AssertionTest.java:12)

Dès que l'on voit AssertionError, c'est qu'on a une assertion qui n'est pas vraie, et que donc on a fait un appel qui ne respecte pas les préconditions. On voit aussi dans le message d'erreur la méthode dans laquelle le problème est apparu : dans notre exemple, la méthode divide.

On peut également ajouter un message qui s'affichera dans le message d'erreur avec l'instruction assert, il suffit de mettre une chaine de caractère après l'expression booléenne, séparant cette expression de la chaine avec deux-points :.

1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
/**
* Divise deux entiers
*
* @pre b != 0
* @post La valeur renvoyée contient le quotient de a par b
*/
public int divide (int a, int b)
{
    assert b != 0 : "Pré violée, b est nul";
 
    return a / b;
}
listing j7.15 Écrire une assertion (2)

Maintenant, si une erreur se produit, on aura un message un peu plus complet et lisible pour un humain, par exemple

Exception in thread "main" java.lang.AssertionError: Pré violée, b est nul
	at Test.divide(Test.java:79)
	at Test.main(Test.java:86)

Assertion et débogage

Dans un programme bien écrit, lorsqu'on fait appel à une méthode, on respecte toujours les préconditions, donc les assertions faites seront toujours vérifiée et jamais le programme ne s'arrêtera avec un message d'erreur de type java.lang.AssertionError. D'ailleurs, l'instruction assert est par défaut ignorée par la machine virtuelle Java, il faut préciser une option pour que celle-ci traite les assertions.

À quoi servent alors les assertions ? C'est un outil de débogage utilisé pendant la phase de développement d'un programme. Les assertions ne sont donc absolument pas à utiliser pour gérer des erreurs et des cas spéciaux dans un programme, on les utilise pour marquer qu'une expression booléenne devrait toujours être vraie à un endroit du code, ainsi, pendant la phase de développement, si cette expression se révèle être fausse, le programme s'arrête en vous signalant quelle condition a été violée.

  • Espace membre
  • Learning Center
  • Les forums
  • Livre d'or
  • Imprimer
  • Boutique
  • Info
  • Règlement
  • Erreur
  • Newsletter

MyPagerank.Net

Firefox 3.6

Browse Happy logo

Open Clip Art Library

Join our Facebook Group

Twitter

Copyright © 2000-2018 UKO. Toute reproduction strictement interdite sans autorisation du webmaster

Valid XHTML 1.1 !
Valid CSS2 !
Level Triple-A conformance icon, W3C-WAI Web Content Accessibility Guidelines 1.0
ICRA Internet Content Rating Association
Creative Commons License
Site optimisé pour Firefox avec une résolution 1024x768 --- Page chargée en 0.0625441 secondes --- This site uses Thumbshots previews