La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Le test de logiciel Yves Le Traon

Présentations similaires


Présentation au sujet: "Le test de logiciel Yves Le Traon"— Transcription de la présentation:

1 Le test de logiciel Yves Le Traon Yves.letraon@francetelecom.com
Benoit Baudry

2 Objectifs du cours Test de composants « unitaires »
classes ou {classes} Assemblage de composants Le problème du test d’intégration Test d’un composant depuis ses exigences ou ses cas d’utilisation – test « système »

3 Objectifs du cours À chaque étape, une technologie (outillée) est choisie Un ou plusieurs exemples sont traités en TD et en TP La notion de « contrat » est importante Pré/post conditions Langage prédominant : Java

4 Plan Problématique du test Rappels test de logiciel
Test de composants unitaires OO Test d'intégration Test système Diagnostic

5 Problématique du test On ne peut pas tester tout le temps ni tous les cas possibles Il faut des critères pour choisir les cas intéressants et la bonne échelle pour le test Prouver l’absence d’erreurs dans un programme est un problème indécidable il faut des heuristiques réalistes

6 Problématique du test analyse des besoins spécification Implémentation
Le coût du test dans le développement analyse des besoins Implém. spécification Spécif. Test An. b Implémentation Pour comprendre ce problème, étudions tout d’abord la courbe de variations du taux de pannes d’un composant. Puisqu’une architecture parallèle est un assemblage de composants élémentaires tels que les processeurs et les liens, il est possible de considérer le même comportement du taux de pannes, mais bien sûr aux valeurs du taux de pannes et des périodes considérées près. test + maintenance = 80 % du coût global de développement !!!

7 Problématique: une définition !
La validation conformité du produit par rapport à sa spécification Vérification/preuve Pour comprendre ce problème, étudions tout d’abord la courbe de variations du taux de pannes d’un composant. Puisqu’une architecture parallèle est un assemblage de composants élémentaires tels que les processeurs et les liens, il est possible de considérer le même comportement du taux de pannes, mais bien sûr aux valeurs du taux de pannes et des périodes considérées près. tests

8 Problématique du test Pourquoi ? Coût Effort Confiance
Pour comprendre ce problème, étudions tout d’abord la courbe de variations du taux de pannes d’un composant. Puisqu’une architecture parallèle est un assemblage de composants élémentaires tels que les processeurs et les liens, il est possible de considérer le même comportement du taux de pannes, mais bien sûr aux valeurs du taux de pannes et des périodes considérées près. Confiance

9 Vocabulaire Testabilité faute bogue erreur Fiabilité (Reliability)
défaillance Test de Robustesse Test statique Test de non-régression Tolérance aux fautes Séquence de test Données de test Sûreté de fonctionnement (Dependability) Jeu de test Test statistique Cas de test

10 Défaillances Catastrophe humaine ou financière: Image de marque :
Automobile (2004) – régulateur de vitesse Therac-25 ( ) – radiologie et contrôle d'injection de substances radioactives London Ambulance System (1992) – central et dispatch ambulances Iran Air Flight 655 (1988) – guerre d'Irak et missile américain – système radar Ariane 5 (1996) SI du FBI (2005) – SI qui n'a pas pu être déployé Mars Climate Orbiter (1999) – kilos – pounds Bourse de Londres (Taurus, 1993) – SI qui n'a pas pu être déployé Image de marque : FT et Bouygues en 2004 – crash des serveurs – indisponibilité 48h Succès financier: Windows Sans conséquence mais énervant : bogue Irisa automobile: therac – 25 : ~10 morts london ambulance : plusieurs morts iran air : 290 morts Ariane : SI FBI : 170 M $ mars climate orbiter : Taurus : 525 M £

11 Dues à des bugs USS Yorktown (1998) Ariane 5 (1996)
Une division par zéro coupe les moteurs Ariane 5 (1996) Mauvaise réutilisation Mars orbiter (1999) Plusieurs unités de mesure Système de guidage (2002) Initialisation erronée The Patriot and the Scud mauvais arrondi dans une soustraction

12 Dues au processus Therac-25 (official report)
The software code was not independently reviewed. The software design was not documented with enough detail to support reliability modelling. The system documentation did not adequately explain error codes. AECL personnel were at first dismissive of complaints. The design did not have any hardware interlocks to prevent the electron-beam from operating in its high-energy mode without the target in place. Software from older models had been reused without properly considering the hardware differences. The software assumed that sensors always worked correctly, since there was no way to verify them. (see open loop) Arithmetic overflows could cause the software to bypass safety checks. The software was written in assembly language. While this was more common at the time than it is today, assembly language is harder to debug than high-level languages. ….

13 Processus (cf. IEEE Spectrum 09/2005)
Système d’information du FBI abandonné en avril 2005 : coût 170 M $ mauvaise spécification, exigences mal exprimées réutilisation dans un contexte inadapté trop d’acteurs concurrents (hommes politiques, agents secrets, informaticiens)

14 Problématique du test Un jeune diplômé sur trois commence par faire du test 50% des start-up échouent à cause du trop grand nombre de bugs mauvaise campagne de test maintenance difficile pas de non régression

15 2- Rappels test de logiciel
2.1. Le test : quoi et comment 2.2. Etapes et processus de test 2.3. Génération de test

16 2- Rappels test de logiciel
2.1. Le test: quoi et comment 2.2. Etapes et processus de test 2.3. Génération de test

17 Le test Essayer pour voir si ça marche. Apprendre pourquoi c’est fait
ce que ça doit faire comment c’est fait comment ça marche modéliser s’en faire une idée exécuter analyser Qu’y a-t-il à voir? Que faut-il regarder? Qu’est-ce qui est visible? Qu’est ce qu’on cherche? Comment le regarder? qu’est ce qui devrait marcher? identifier une erreur diagnostiquer une erreur catégoriser ces erreurs

18 Qu’est-ce qu’on teste? (quelles propriétés?)
fonctionnalité sécurité / intégrité utilisabilité cohérence maintenabilité efficacité robustesse sûreté de fonctionnement

19 Comment on teste? Test statique Test dynamique
relecture / revue de code analyse automatique (vérification de propriétés, règles de codage... Test dynamique on exécute le programme avec des valeurs en entrée et on observe le comportement

20 Avec quoi on teste? Une spécification: exprime ce qu’on attend du système un cahier des charges (en langue naturelle) commentaires dans le code contrats sur les opérations (à la Eiffel) un modèle UML une spécification formelle (automate, modèle B...)

21 Exemple Comment tester la classe StringList? Comment écrire ces tests?
tester l’ajout dans une liste vide tester l’ajout dans une liste avec un élément tester le retrait dans une liste avec deux éléments .... d’abord il fau comprendre comment ça marche : * ici les noms sont significatifs et on connait grosso modo le fonctionnement d’une liste * mais il manque la spec exacte du code, du fonctionnement de chaque méthode quand on connait la spec, il faut choisir ce qu’on va tester: * technique simple: au moins un test par méthode publique * choisir un ordre pour les tests, choisir les paramètres on sait qu’on ne peut pas tester tous les cas, il faut donc choisir et savoir quand on a assez testé il faut aussi exécuter les tests, pouvoir les relancer... Comment écrire ces tests? Comment les exécuter? Les tests sont-ils bons? Est-ce que c’est assez testé? ...

22 Test de logiciel Spécification Programme Test Résultat décrit implante
Résultat attendu Test Résultat Comparer Test échoue différent Test passe égal

23 2- Rappels test de logiciel
2.1. Le test : quoi et comment 2.2. Etapes et processus de test 2.3. Génération de test

24 Test de logiciel Plusieurs échelles: Plusieurs techniques
Unitaire, intégration, système Plusieurs techniques Dynamique / statique Génération de test Fonctionnel / structurel

25 Cycle de vie en V (normalisé AFNOR)
Analyse Validation • Expression du besoin • Validation • Analyse détaillée • Mise en œuvre Conception Intégration • Etude technique préalable • Intégration • Conception préliminaire • Tests d'Intégration • Conception détaillée Réalisation • Codage • Mise au point • Tests unitaires

26 Hiérarchisation des tests
Maintenance Problème Programme livrable analyse des besoins Test de recette (avec client) Définition des besoins Plan de test système (fonctionnel) Système Tests systèmes Cahier des charges Conception globale Plan de test d’intégration Tests d ’intégration Intégration ? Composants unitaires Tests unitaires Conception détaillée implémentation le cycle en « V » programme

27 Cycle de vie en « spirale »
Intégration Réalisation Conception Analyse détaillée Analyse préliminaire « (de risque) » V1 V2 Validation Synergie avec approche par objets

28 Test unitaire Validation d’un module indépendamment des autres
Valider intensivement les fonctions unitaires Les unités sont-elles suffisamment spécifiées? le code est-il lisible, maintenable...?

29 Test unitaire Pour un langage procédural
unité de test = procédure Dans un contexte orienté objet unité de test = classe void Ouvrir (char *nom, Compte *C, float S, float D ) { C->titulaire = AlloueEtCopieNomTitulaire(nom); (*C).montant = S ; (*C).seuil = D ; (*C).etat = DEJA_OUVERT ; (*C).histoire.nbop = 0; EnregistrerOperation(C); EcrireTexte("Ouverture du compte numero "); EcrireEntier(NumeroCourant+1); EcrireTexte(", titulaire : \""); EcrireTexte(C->titulaire); EcrireCar('"'); ALaLigne(); }

30 Test d’intégration Choisir un ordre pour intégrer et tester les différents modules du système

31 Test d’intégration Cas simple: il n’y a pas de cycle dans les dépendances entre modules Les dépendances forment un arbre et on peut intégrer simplement de bas en haut

32 Test d’intégration LOCAL_NAME ARGUMENT_NAME NAME + is_manifest_string : Boolean + is_result : Boolean + is_void : Boolean TYPE_CLASS (from TYPE) GLOBALS PROCEDURE DEFERRED_ROUTINE DEFERRED_PROCEDURE WRITABLE_ATTRIBUTE ONCE_ROUTINE ONCE_PROCEDURE E_CHECK E_RETRY REVERSE_ASSIGNMENT ROUTINE CALL ONCE_FUNCTION FUNCTION DEFERRED_FUNCTION ATTRIBUTE DECLARATION_LIST DECLARATION + count : Integer EXPRESSION CST_ATT PROC_CALL ASSIGNMENT TYPE CREATION_CALL +call +type DECLARATION_1 DECLARATION_GROUP RENAME_PAIR (from InheritanceClause) EXPORT_ITEM +result_type 1 +writable LOCAL_ARGUMENT +name +name_list FORMAL_GENERIC_LIST PARENT +rename_list +export_list CALL_PROC_CALL +target 0..* +arguments FEATURE_NAME_LIST +undefine_list +redefine_list +select_list CLASS_NAME SMALLEIFFEL + magic_count : Integer + is_ready : Boolean + load_class() + get_started() + falling_down() + afd_check() PARENT_LIST FEATURE_NAME + is_frozen : Boolean +to_runnable FEATURE_CLAUSE_LIST CREATION_CLAUSE_LIST CLIENT_LIST +list BASE_CLASS + path : String + is_deferred : Boolean + is_expanded : Boolean /+ is_generic : Boolean + is_any : Boolean = initval + is_general : Boolean +base_class +base_class_dictionary +parent_list +origin_base_class +feature_clause_list +creation_clause_list FORMAL_ARG_LIST FEATURE_CLAUSE +clients CREATION_CLAUSE E_FEATURE + is_deferred : Boolean = initval +procedure_list +names INFIX_NAME PREFIX_NAME FROZEN_FEATURE_NAME WHEN_ITEM_1 LOCAL_VAR_LIST INSTRUCTION E_LOOP IFTHENELSE IFTHEN E_DEBUG EFFECTIVE_ROUTINE COMPOUND +then_compound WHEN_ITEM WHEN_LIST E_INSPECT E_WHEN SIMPLE_FEATURE_NAME EXTERNAL_FUNCTION EXTERNAL_PROCEDURE NATIVE EXTERNAL_ROUTINE +native NATIVE_C NATIVE_SMALL_EIFFEL NATIVE_JVM TYPE_GENERIC FORMAL_GENERIC_ARG + constrained : boolean + rank : Integer TYPE_FORMAL_GENERIC +formal_generic_list / path : String +generic_list +constraint +current_type TYPE_ANY TYPE_CHARACTER TYPE_POINTER TYPE_NONE Cas plus complexe: il y a des cycles dans les dépendances entre modules Cas très fréquent dans les systèmes à objets Il faut des heuristiques pour trouver un ordre d’intégration

33 Test système Valider la globalité du système Les fonctions offertes
A partir de l’interface

34 Test de non régression Consiste à vérifier que des modifications apportées au logiciel n’ont pas introduit de nouvelle erreur vérifier que ce qui marchait marche encore Dans la phase de maintenance du logiciel Après refactoring, ajout/suppression de fonctionnalités Après la correction d’une faute

35 Etapes et hiérarchisation des tests
Test structurel Tests unitaires Tests d ’intégration Tests système Test fonctionnel

36 2- Rappels test de logiciel
2.1. Le test : quoi et comment 2.2. Etapes et processus de test 2.3. Génération de test

37 Le test dynamique : processus
Donnée de test Programme P Génération de données de test Exécution Résultat Spécification S Oracle Oracle Localisation / Mise au point faux Problèmes Verdict vrai Diagnostique non vérifié Critère d’arrêt

38 Le test dynamique de logiciel
Soit D le domaine d’entrée d’un programme P spécifié par S, on voudrait pouvoir dire Soit D le domaine de P:  xD P(x) = S(x) Test exhaustif impossible dans la plupart des cas Domaine D trop grand, voire infini Trop long et coûteux

39 Le test dynamique On cherche alors un ensemble de données de test T tel que T  D si  xT P(x) = S(x) alors  xD P(x) = S(x) Critère d’arrêt pour la génération de données de test {données de test} = T

40 La génération de test Test fonctionnel (test boîte noire)
Utilise la description des fonctionnalités du programme Test structurel (test boîte blanche) Utilise la structure interne du programme I1 I2 I3 O1 O2 I1 I2 I3 O1 O2

41 Test fonctionnel Spécification formelle Description en langage naturel
Modèle B, Z Automate, système de transitions Description en langage naturel UML Use cases Diagramme de classes (+ contrats) Machines à états / diagramme de séquence

42 Test structurel A partir d’un modèle du code
modèle de contrôle (conditionnelles, boucles...) modèle de données modèle de flot de données (définition, utilisation...) Utilisation importante des parcours de graphes critères basés sur la couverture du code

43 Génération de test Génération déterministe
« à la main » Génération automatique aléatoire Génération automatique aléatoire contrainte mutation test statistique Génération automatique guidée par les contraintes

44 Génération de test Reste à savoir quand on a suffisamment testé
critères de test structurels, fonctionnels analyse de mutation Choisir le bon niveau pour le test

45 Exemple de test unitaire structurel
PGCD de 2 nombres Précondition: p et q entiers naturels positifs pgcd: integer is local p,q : integer; do read(p, q) B1 while p<> q do P1 if p > q P2 then p := p-q B2 else q:= q-p B3 end -- if end -- while result:=p B4 end-- pgcd E B1 P1 P2 B2 B3 S B4 p<>q p=q p>q p<q

46 Exemple de test unitaire structurel
B1 P1 P2 B2 B3 S B4 p<>q p=q p>q p<=q Tous les noeuds: (E, B1, P1, P2, B2, P1, B4, S) (E, B1, P1, P2, B3, P1, B4, S) Tous les arcs : idem Tous les chemins élémentaires (1-chemin) : idem + (E, B1, P1, B4, S) Tous les 2-chemins : idem + (E, B1, P1, P2, B2, P1, P2, B2, P1, B4, S) (E, B1, P1, P2, B2, P1, P2, B3, P1, B4, S) (E, B1, P1, P2, B3, P1, P2, B2, P1, B4, S) (E, B1, P1, P2, B3, P1, P2, B3, P1, B4, S)

47 Techniques de test fonctionnel
Test « boite noire » N’utilise que la description fonctionnelle du programme c’est la spécification Plusieurs informations domaine d’entrée scénarios use cases ...

48 Domaine d’entrée Plusieurs niveaux
type des paramètres d’une méthode pré-condition sur une méthode ensemble de commandes sur un système grammaire d’un langage ... On ne peut pas tout explorer, il faut délimiter Génération aléatoire Analyse partitionnelle Test aux limites Graphe causes - effets

49 Technique 1: Analyse partitionnelle
A partir de la spécification déterminer le domaine d’entrée du programme Partitionner le domaine d’entrée en classes d’équivalences identifier des classes d’équivalence pour chaque donnée les classes d’équivalence forment une partition du domaine de chaque donnée en entrée choisir une donnée dans chacune

50 Technique 2 : Test aux limites
Intuition: de nombreuses erreurs se produisent dans les cas limites Pour chaque donnée en entrée déterminer les bornes du domaine prendre des valeurs sur les bornes et juste un peu autour Exemple pour un intervalle [1, 100] 1, 100, 2, 99, 0, 101

51 Technique 2 : Test aux limites
Le programme lit trois nombres réels qui correspondent à la longueur des côtés d’un triangle. Si ces trois nombres ne correspondent pas à un triangle, imprimer un message d’erreur. S’il s’agit d’un triangle, le programme détermine s’il est isocèle, équilatéral ou scalène et si son plus grand angle est aigue, droit ou obtus.

52 Analyse partitionnelle
aigu obtus droit scalène 6,5,3 5,6,10 3,4,5 isocèle 6,1,6 7,4,4 2,2,2 équilatéral 4,4,4 impossible

53 1, 1, 2 non triangle 0, 0, 0 un seul point 4, 0, 3 unes des longueurs est nulle 1, 2, presque triangle 0.001, 0.001, 0.001 très petit triangle 88888, 88888, 88888 très grand , 3, 3 presque équilatéral , 3, 4 presque isocèle 3, 4, presque droit 3, 4, 5, 6 quatre données 3 une seule donnée 5, 5, A une lettre pas de donnée -3, -3, 5 données négatives ...

54 Structurel/fonctionnel: conclusion
Les critères structurels et fonctionnels sont complémentaires une erreur d’omission ne peut pas être détectée par le test structurel du code mort ne peut pas être détecté par le test fonctionnel Au niveau unitaire on commence par le test fonctionnel on complète par du test structurel

55 Oracle Fonction qui évalue le résultat d’un cas de test
Plus formellement soit un programme P: Dom(P) → Ran(P) une spécification S: Dom(P) → Ran(P) une donnée de test X  Dom(P) oracle O: Dom(P) × Ran(P) → bool O(X, P(X)) = true iff P(X) = S(X) Problème : comment comparer P(X) et S(X) plus S est formalisé plus on peut automatiser

56 Oracle Oracle manuel: on « regarde » le résultat et un humain évalue s’il est bon Construire le résultat attendu Assertions dans le code (programmation défensive) aux interfaces (design by contract) set_current_node (cnode: Node) pre : cnode != null post : currentNode = cnode dans les cas de test (par ex. JUnit) ...

57 Quelques notions importantes pour conclure
La relecture >> au test dynamique La non-régression est fondamentale et implique la capacité à mémoriser les tests On verra aussi que les contrats/assertions peuvent servir d’oracle embarqués

58 Plan Problématique du test Rappels test de logiciel
Test de composants unitaires OO Test d'intégration Test système Diagnostic

59 3- Test unitaire de composants 00
3.1. Introduction au test unitaire de composants 00 - composant 00 "de confiance" - l'unité = la classe - sentiment mitigé des testeurs 3.2. JUnit le cas particulier du test unitaire en Java 3.3. Test-driven development (TDD) 3.4. Fiabilisation de composants par analyse de mutation

60 Composant 00 de confiance
Unité de réutilisation Unité de déploiement Pour le testeur = quelles sont les caractéristiques dont doit être doté un composant pour être fiable/testable ? Quelle est la complexité d'un composant ?

61 Unité vs. système Juste une question de granularité
En OO et pour les composants, un système est un composant au même titre qu’un composant unitaire La distinction unité/système est maintenue en raison du processus industriel

62 Intérêts des composants
Encapsulation Pas besoin de savoir comment est fabriqué un composant pour l’utiliser Ça marche (i.e. il y a un marché)

63 Faiblesses des composants
Encapsulation Il faut savoir très précisément ce qu’il fait pour l’utiliser Sentiment mitigé pour les systèmes critiques Elaine J. Weyuker’ “Testing Component-Based Software: A Cautionary Tale”, IEEE Software Sep-Oct 1998 Ariane 501

64 Confiance fondée sur la cohérence
Composant fiable Spécification contrats exécutables V & V: ensemble de cas de test Confiance fondée sur la cohérence Un composant -> trois aspects Implantation

65 Conclusion composant Sont de granularité variable
Pour nous : composant unitaire = classe Les contrats  oracles embarqués

66 Le test des logiciels à objets
Au départ, une certaine méfiance des testeurs…

67 Mixed-feeling at the code level
Flôt d’appels de méthodes pour exécuter C.m1() L’effet Yo-Yo (Binder, Offut) A m1() m2() m3() m4() B w C calls m4() calls m2() A.m1() C.m4() B.m2() B.m1() calls super() Implements C.m1()

68 Test unitaire OO Tester une unité isolée du reste du système
L’unité est la classe Test unitaire = test d’une classe Test du point de vue client les cas de tests appellent les méthodes depuis l’extérieur on ne peut tester que ce qui est public Le test d’une classe se fait à partir d’une classe extérieure Au moins un cas de test par méthode publique Il faut choisir un ordre pour le test quelles méthodes sont interdépendantes?

69 Test unitaire OO Problème pour l’oracle :
Encapsulation : les attributs sont souvent privés Difficile de récupérer l’état d’un objet Penser au test au moment du développement (« testabilité ») prévoir des accesseurs en lecture sur les attributs privés des méthodes pour accéder à l’état de l’objet

70 Cas de test unitaire Cas de test = une méthode Corps de la méthode
Configuration initiale Une donnée de test un ou plusieurs paramètres pour appeler la méthode testée Un oracle il faut construire le résultat attendu ou vérifier des propriétés sur le résultat obtenu Une classe de test pour une classe testée Regroupe les cas de test Il peut y avoir plusieurs classes de test pour une classe testée

71 Exemple Comment tester la classe StringList? Comment écrire ces tests?
tester l’ajout dans une liste vide tester l’ajout dans une liste avec un élément tester le retrait dans une liste avec deux éléments .... d’abord il fau comprendre comment ça marche : * ici les noms sont significatifs et on connait grosso modo le fonctionnement d’une liste * mais il manque la spec exacte du code, du fonctionnement de chaque méthode quand on connait la spec, il faut choisir ce qu’on va tester: * technique simple: au moins un test par méthode publique * choisir un ordre pour les tests, choisir les paramètres on sait qu’on ne peut pas tester tous les cas, il faut donc choisir et savoir quand on a assez testé il faut aussi exécuter les tests, pouvoir les relancer... Comment écrire ces tests? Comment les exécuter? Les tests sont-ils bons? Est-ce que c’est assez testé? ...

72 Exemple : test de StringList
Créer une classe de test qui manipule des instances de la classe StringList Au moins 9 cas de test (1 par méthode publique) Pas accès aux attributs privés : count, LastNode, CurrentNode, FirstNode

73 Exemple: insertion dans une liste
initialisation appel avec donnée de test oracle spécification du cas de test Intention //first test for insert: call insert and see if //current element is the one that's been inserted public void testInsert1(){ StringList list = new StringList(); list.add("first"); list.add("second"); list.insert("third"); assertTrue(list.size()==3); assertTrue(list.item()=="third"); }

74 3- Test unitaire de composants 00
3.1. Introduction au test unitaire 00 3.2. JUnit le cas particulier du test unitaire en Java 3.3. Test-driven development (TDD) 3.4. Fiabilisation de composants par analyse de mutation

75 JUnit Origine Objectifs Xtreme programming (test-first development)
framework de test écrit en Java par E. Gamma et K. Beck open source: Objectifs test d’applications en Java faciliter la création des tests tests de non régression

76 Junit:Framework Un framework est un ensemble de classes et de collaborations entre les instances de ces classes.

77 Junit:Framework Le source d’un framework est disponible
Ne s’utilise pas directement: il se spécialise Ex: pour créer un cas de test on hérite de la classe TestCase Un framework peut être vu comme un programme à « trous » qui offre la partie commune des traitements et chaque utilisateur le spécialise pour son cas particulier.

78 3- Test unitaire de composants 00
3.1. Introduction au test unitaire 00 3.2. JUnit le cas particulier du test unitaire en Java 3.3. Test-driven development (TDD) 3.4. Fiabilisation de composants par analyse de mutation

79 Test-first development
Xtreme programming Écrire les cas de test avant le programme les cas de test décrivent ce que le programme doit faire avant d’écrire le code, les cas de test échouent quand on développe, les cas de test doivent passer Ensuite on développe la partie du programme qui fait passer le cas de test

80 Test-first development
Écrire un cas de test Exemple : ajout dans une liste chainée public void testAdd(){ list.add("first"); assertTrue(list.size()==1); } Exécuter les cas de test succès échec public void add (String it){ Node node = new Node(); node.setItem(it); node.setNext(null); if (firstNode == null) { node.setPrevious(null); this.setFirstNode(node); } lastNode = node; this.setCurrentNode(node); public void add (String it){} développement continue Faire un petit changement Exécuter les cas de test échec développement s’arrête

81 3- Test unitaire de composants 00
3.1. Introduction au test unitaire 00 3.2. JUnit le cas particulier du test unitaire en Java 3.3. Test-driven development (TDD) 3.4. Fiabilisation de composants par analyse de mutation

82 Trusting Components? ? Component The point of view of the user...
Components “off-the-shelf”

83 Trusting Components? Component The point of view of the user...
“replay” selftests 100% 85% 100% 55% Components “off-the-shelf”

84 Test dependencies between a component and its environment
Trusting Components? Plug-in the component in the system Specification Test Component Impl. System selftest tests Continuity Strategy Test dependencies between a component and its environment

85 Summary The problem: trustable components
Component qualification with mutation analysis Genetic algorithms for test enhancement A new model: bacteriological algorithms for test enhancement A mixed-approach and tuning of the parameters Conclusion First of all, I will present the problem domain. That is testing for trust and selftest approach. And then I will represent component qualification using mutation analyses. Next, I will talk about test enhancement using genetic algorithm. This point corresponds to the main contribution of this paper. The first result obtained on a little case study are presented too. We finish on discussion these results and give out our conclusion on the benefit of such an approach

86 Object-oriented paradigm
Testing for trust Object-oriented paradigm Reuse Safely Trust The main advantage of OO approach is to provide a way to reuse existing components for building a new application. But problem is to be able to reuse safely these components. How can we trust it? It makes us to need some kinds of testing for trust. Our work base on a Maxim’s argument, that is “the better you test, the more trustable your component is”. This consideration leads to “testing for trust approach”. the better you test, the more trustable your component is

87 Testing for trust Specification V & V: checking Implementation
Derived as executable contracts Trust based on Consistency V & V: checking Implementation against Specification In our view, a component is an organic set of three aspects : specification, implementation but also the test, because each time we reuse a component, each time we have to retest it. So, test is embedded in component conception and we call this conception is “three angle view of component” We consider that any trust estimate have to base on the consistency between these three aspects : specification, implementation and test Implementation

88 Trusting Components? The Design of a Trustable Component
Design-by-contract What is the accepted domain of use ? What guarantees the component execution ? Executable Contracts Specifying the Component Implementing it... debug Validating it... Building Unit Tests Implementation OK No Trust Test Quality Estimate Embedding Test Suite Self-Tests Trust

89 Intuition The better a program is tested the more trust we can have
How can we evaluate the quality of testing? Mutation analysis If test can detect faults that are seeded intentionally, they can detect real faults in the program

90 Analyse de mutation R. DeMillo, R. Lipton and F
Analyse de mutation R. DeMillo, R. Lipton and F. Sayward, "Hints on Test Data Selection : Help For The Practicing Programmer". IEEE Computer 11(4): April 1978. Technique pour évaluer l’efficacité d’un ensemble de cas de test Injection d’erreurs dans le programme sous test Calcul de la proportion d’erreurs détectées par les cas de test Moyen courant de valider une technique de test Puissance de calcul Technique ancienne mais praticable que récemment car machines puissantes et peu d’opérateurs

91 Analyse de mutation Différents types d’erreur : opérateurs de mutation
Opérateurs définis à partir d’observations des bases d’erreurs établies au cours du développement J. Offutt, A. Lee, G. Rothermel, R. H. Untch and C. Zapf, "An Experimental Determination of Sufficient Mutant Operators". ACM Transactions on Software Engineering and Methodology 5(2): April 1996. Travaux récents [Ma’02, Alexander’02] proposent des opérateurs spécifiques pour logiciels OO Depuis 3 ans explosion des travaux et utilisation pour valider technique de test

92 Analyse de mutation Programme erroné : mutant
Cas de test qui détectent les mutants Cas de test tuent les mutants Score de mutation Proportions de mutants tués  efficacité des cas de test Deux fonctions d’oracle Différence de traces Contrats exécutables

93 Limited Mutation Analysis
- 1 put (x : INTEGER) is -- put x in the set require not_full: not full do 1 if not has (x) then 2 count := count + 1 3 structure.put (x, count) end -- if ensure has: has (x) not_empty: not empty end -- put Remove-inst

94 Overall Process Error detected Error not detected Enhance test
Generation of mutants mutantA6 mutantA5 mutantA4 mutantA3 mutantA2 mutantA1 Class A Selftest A Test Execution 2 Enhance test Automated process Non automated process Error detected Error not detected mutantAj killed mutantAj  alive  Equivalent mutant 1 Consider Aj as Diagnosis

95 About Living Mutants What if a mutant is not killed?
Tests inadequate => add more tests Equivalent mutant => remove mutant (or original!) e.g., x<y ? x:y <=> x<=y ? x:y

96 Quality Estimate = Mutation Score
Q(Ci) = Mutation Score for Ci = di/mi di = number of mutants killed mi = number of mutants generated for Ci WARNING: Q(Ci)=100% not=> bug free Depends on mutation operators (see next slide) Quality of a system made of components Q(S) = S di / S mi

97 Outline of a Testing Process
Select either: Quality Driven: select wanted quality level = Q(Ci) Effort Driven: Maximum #test cases = MaxTC Mutation Analysis and Test Cases Enhancement while Q(Ci) < Q(Ci) and nTC <= MaxTC enhance the test cases (nTC++) apply test cases to each mutant Eliminates equivalent mutants computes new Q(Ci)

98 Component qualification
Type Description EHF Exception Handling Fault AOR Arithmetic Operator Replacement LOR Logical Operator Replacement ROR Relational Operator Replacement NOR No Operation Replacement VCP Variable and Constant Perturbation MCR Methods Call Replacement RFI Referencing Fault Insertion Mutation operators

99 Mutation operators (1) Exception Handling Fault
causes an exception Arithmetic Operator Replacement replaces e.g., ‘+’ by ‘-’ and vice-versa. Logical Operator Replacement logical operators (and, or, nand, nor, xor) are replaced by each of the other operators; expression is replaced by TRUE and FALSE.

100 Mutation operators (2) Relational Operator Replacement
relational operators (<, >, <=, >=, =, /=) are replaced by each one of the other operators. No Operation Replacement Replaces each statement by the Null statement. Variable and Constant Perturbation Each arithmetic constant/variable: ++ / -- Each boolean is replaced by its complement.

101 Mutation operators (3) Referencing Fault Insertion (Alias/Copy)
Nullify an object reference after its creation. Suppress a clone or copy instruction. Insert a clone instruction for each reference assignment.

102 A test report 119 mutants, 99 dead, 15 equivalents MS= 99/104=95%
id_mut EQ METHODE SOURCE MUTANT COMMENTAIRE 2 1 empty count = lower_bound – 1 count <= jamais < 6 full upper_bound count >= jamais > 16 3 index_of – loop variant count + 2 count * même 24 4 index_of – loop until or else structure or court test 30 5 make := 0 ( nul) valeur défaut 45 lower_bound, lower_bound – 1 ), redondance 46 7 lower_bound, ( + 1 ) 60 I = test insuf. 63 II upper_bound; ); 72 III put if not has (x) then true Spec inc. 75 IV not false 98 8 - Result) - Result 99 9 - 1 100 10 count + 2 - (count + 2 ) - 101 11 102 12 (count ) + 2 - 103 13 104 14 + 2 - (count + 105 15 110 V > count or > (count ) or test insuf. NON EQUIVALENT EQUIVALENT 119 mutants, 99 dead, 15 equivalents MS= 99/104=95%

103 Oracle Oracle par différence de comportements
Des traces Des objets « programmes » Oracle embarqués (contrats, assertions) Interne au composant Oracle associé aux données de test Extérieur au composant Oracle spécifique à la donnée de test

104 Global Process Automated process equivalent mutants suppression
remaining bugs correction automatic optimization of the initial tests set initial tests generation and bugs correction (tester’s work). measure contracts efficiency Improve contracts Oracle function reconstruction 1 2 3 4 5 6 MS= trust contracts test impl. contracts test impl. MS= trust contracts test impl. contracts test impl. contracts test impl. MS=trust contracts test impl. MS=trust

105 Partial conclusion An effective method to build (some level of) ‘trust’ estimate the quality a component based on the consistency of its 3 aspects: specification (contract) tests implementation be a good basis for integration and non-regression testing A tool is currently being implemented for languages supporting DbC: Eiffel, Java (with iContract), UML (with OCL+MSC) ...


Télécharger ppt "Le test de logiciel Yves Le Traon"

Présentations similaires


Annonces Google