830 likes | 1.32k Views
Plan. Problématique du test Rappels test de logiciel Test de composants unitaires OO Test d'intégration Test système Diagnostic. Test d’intégration pour des systèmes à objets. Yves Le Traon yletraon@irisa.fr Yves.letraon@francetelecom.com. Plan. Problématique du test
E N D
Plan • Problématique du test • Rappels test de logiciel • Test de composants unitaires OO • Test d'intégration • Test système • Diagnostic
Test d’intégration pour des systèmes à objets Yves Le Traon yletraon@irisa.fr Yves.letraon@francetelecom.com
Plan • Problématique du test • Rappels test de logiciel • Test de composants unitaires OO • Test d'intégration • L’intégration: approches classiques • Le test d’intégration de classes par l’exemple • L’approche à objets et l’intégration • Modélisation et stratégies d’ordonnancement • Test système • Diagnostic
Plan • Problématique du test • Rappels test de logiciel • Test de composants unitaires OO • Test d'intégration • L’intégration: approches classiques • Le test d’intégration de classes par l’exemple • L’approche à objets et l’intégration • Modélisation et stratégies d’ordonnancement • Test système • Diagnostic
Contexte • Réalisation d’une « bonne » stratégie : • pour planifier l’intégration des systèmes à objets, • le plus tôt possible dans le cycle de vie, • en minimisant le coût du test.
Test d’intégration • Objectif • Vérifier l’interaction entre unités (méthode, classe ou package). • Difficultés principales de l’intégration • Interfaces floues (ex. ordre des paramètres de même type). • Implantation non conforme à la spécification (ex. dépendances entre unités non spécifiées). • Réutilisation d’unités (ex. risque d’utilisation hors domaine).
Unité à tester Dépendance à tester Architecture de dépendances
Intégration – Approches classiques • On obtient une architecture arborescente • SADT, SART, SAO (Aérospatiale) • Approches • Big-Bang : non recommandé • De haut en bas (top-down) • De bas en haut (bottom-up)
Unité à tester Dépendance à tester Unité sous test Dépendance sous test Bouchon de test (stub) Dépendance simulée Unité testée Dépendance testée Approche classique : De haut en bas
Unité à tester Dépendance à tester Unité sous test Dépendance sous test Unité testée Dépendance testée Approche classique : De bas en haut
Plan • Problématique du test • Rappels test de logiciel • Test de composants unitaires OO • Test d'intégration • L’intégration: approches classiques • Le test d’intégration de classes par l’exemple • L’approche à objets et l’intégration • Modélisation et stratégies d’ordonnancement • Test système • Diagnostic
Intégration • But : tester les interactions entre classes • Lien entre test d’intégration et unitaire: • il faut ordonner les classes pour le test • Il faut identifier les dépendances entre classes • Problème dans le cas de cycles de dépendances
A B E D C F Graphe de dépendances acyclique Cas simple : un graphe acyclique Ordre partiel pour le test: F, (C, D), E, B, A
Operation Account Display Bank WOp DOp Person Cas moins simple: présence de cycles
Intégration avec cycles • Il faut casser les cycles • développer des simulateurs de classes (« bouchon de test » ou « stub ») • un simulateur a la même interface que la classe simulée, mais a un comportement contrôlé • Exemple
Exemples de stub /** * Creates an account for the person named name * If no client has this name, a new client object is created and is added to the list of clients, then the account is created * If the client exists the account is created, added to the bank's and the client's list of accounts */ public int addAccount(String name, float amount, float overdraft) { this.accountNumbers++; Person p = getClient(name); //if a client named name already exists in the bank's set of clients if (p!=null){ Account a = new Account(p, amount, overdraft, accountNumbers); p.addAccounts(a); this.addAccounts(a); } //if the client does not exist, add it tp the bank's list of clients and create account else{ Person client = new Person(name); this.addClients(client); Account a = new Account(client, amount, overdraft, accountNumbers); client.addAccounts(a); this.addAccounts(a); } return accountNumbers; }
Exemples de stub Stub 1 /** * Creates an account for the person named name * If no client has this name, a new client object is created and is * added to the list of clients, then the account is created * If the client exists the account is created, added to the bank's and the client's list of accounts */ public int addAccount(String name, float amount, float overdraft) { return 0; } Stub 2 /** * Creates an account for the person named name * If no client has this name, a new client object is created and is * added to the list of clients, then the account is created * If the client exists the account is created, added to the bank's and the client's list of accounts */ public int addAccount(String name, float amount, float overdraft) { return 1; }
Exemples de stub /** * Looks for a person named name in the set of clients. * Returns the Person object corresponding to the client if it exists * Returns null if there is no client named name */ public Person getClient(String name) { Iterator it = this.clientsIterator(); while (it.hasNext()){ Person p = (Person)it.next(); if(p.getName()==name){ return p; } } return null; }
Exemples de stub Stub 1 /** * Looks for a person named name in the set of clients. * Returns the Person object corresponding to the client if it exists * Returns null if there is no client named name */ public Person getClient(String name) { return null; } Stub 2 /** * Looks for a person named name in the set of clients. * Returns the Person object corresponding to the client if it exists * Returns null if there is no client named name */ public Person getClient(String name) { return new Person(“toto”); }
Account Person Exemple Banque • Exemple, pour tester en présence de ce cycle Regarder quelles sont les méthodes de Person utilisées par Account public class Person { /* * Initializes the name of the person with the param n * Creates a new vector to intialize the acounts set */ public Person(String n){ name = n; accounts = new Vector(); } public String getName(){return name;} } Stub de la classe Person public class Person { /* * Initializes the name of the person with the param n * Creates a new vector to initialize the accounts set */ public Person(String n){ } public String getName(){return (“toto”);} }
Exemple Banque • Etape 1 • Tester la classe Account avec le stub de Person • Etape 2 • Tester la classe Person avec Account • Etape 3 • Retester la classe Account avec la vraie classe Person
Plan • Problématique du test • Rappels test de logiciel • Test de composants unitaires OO • Test d'intégration • L’intégration: approches classiques • Le test d’intégration de classes par l’exemple • L’approche à objets et l’intégration • Modélisation et stratégies d’ordonnancement • Test système • Diagnostic
Analyse détaillée Analyse préliminaire « (de risque) » Conception V1 V2 Réalisation Validation Intégration (…) Cycle de vie en « spirale » Synergie avec approche par objets
Test unitaire et d’intégration • Classiquement • Étapes séparées • Dans un cycle en spirale • Un composant unitaire ne peut pas être testé hors de son contexte d’exécution • > conséquence : test unitaire et test d’intégration sont des activités inséparables
Efficient Strategies for Integration and Regression Testing of OO Systems • The problem domain: Use OO modeling for early Test Planning • Integration • deduced from UML models • to master integration cost and duration • Regression • separation of reusable tests from implementation • the test model must be refinable with design refinement stages.
Efficient Strategies for Integration and Regression Testing of OO Systems • A OO test model must • be as simple as possible • easy to understand • limited to its purpose • catch all the information concerning test • test dependencies between components • from a rough to a precise level of detail • (class method) • determine design parts due to implementation choices • test cases reuse • test cases enhancement with system evolution Integration Regression
Efficient Strategies for Integration and Regression Testing of OO Systems Where to begin with ? How to organize test ? • Integration plan - What we have to deal with... problem interdependencies loops of dependencies between components into an architecture
S pck1 pck2 pck4 pck3 Efficient Strategies for Integration and Regression Testing of OO Systems • A simple solution, with constraints on the design • no loops in an architecture • often possible but local optimizations are not always optimal for the architecture but designing interdependent components may also be relevant • The solution presented here • takes any model • optimizes the way to deal with loops of interdependent components
Interdépendance • Interdépendances • Cycle de dépendances • Composantes fortementconnexes (CFC) • Intégration • Big-Bang • Décomposer des CFCs – Utilisation de bouchons
A CA A A C C C’ C B CB B B Bouchon spécifique Bouchon réaliste CFC Décomposition des CFCs – Bouchon • Bouchon : une unité qui • simule le comportement d’une unité • évite l’utilisation des services d’autres unités de la même CFC.
C Test depends on C’ A stub Test depends on B Efficient Strategies for Integration and Regression Testing of OO Systems Integration Testing • Based on a TDG, how to order components ? • Minimizing the number of stubs • realistic stub => dedicated simulator, « old component » C’ stub simulates the behavior of C when A and B are tested
C Test depends on Test depends on Test depends on C’ A A B stub Test depends on C’’ B stub Efficient Strategies for Integration and Regression Testing of OO Systems • Minimizing the number of stubs • specific stub => deterministic component behavior A stub for A and a stub for B
Plan • Problématique du test • Rappels test de logiciel • Test de composants unitaires OO • Test d'intégration • L’intégration: approches classiques • Le test d’intégration de classes par l’exemple • L’approche à objets et l’intégration • Modélisation et stratégies d’ordonnancement • Test système • Diagnostic
Problème de test d’intégration • Modéliser la structure de dépendances • Décomposer des composantes fortement connexes en minimisant le coût de création des bouchons • Planifier le test.
Efficient Strategies for Integration and Regression Testing of OO Systems The Test Dependency Graph preliminary modeling inheritance • Two basic types of test dependencies client/provider Contractual dependencies = • specified in the public part of classes • included in the body of internal methods Implementation dependencies = not contractual ones
A A Class A Class node A … mA1(…) ... A mA1 Method mA1 in Class A Method node in a class node Efficient Strategies for Integration and Regression Testing of OO Systems The Test Dependency Graph preliminary modeling 2 types of nodes • class node • method node
Semantic of a directed edge A is test dependent from B A B Efficient Strategies for Integration and Regression Testing of OO Systems The Test Dependency Graph preliminary modeling 3 types of edges • class_to_class • method_to_class • method_to_method …
Efficient Strategies for Integration and Regression Testing of OO Systems Method_to_class A ... +mA1(...v1: B...) … mA2(…v: A…) ... B A mA1 mA2 refinement Method_to_method A +mA1(...v: B...) {… v.mB1 …} +mA2(...v: A...) {… v.mA1 …} B A mB1 mA1 mA2 … an action language (ASL/OCL) code level
B A A C B C association class A A A A Interface Name B A B B B B inheritance Interfaces dependency navigability A A B B association Efficient Strategies for Integration and Regression Testing of OO Systems Class-to-class A A B B aggregation composition
Modélisation statique 1/2 B A B A h A A Une classe Un nœud A A A A A A A A A A B B B B B B B B B B