Vous êtes sur la page 1sur 75

Cours Test Logiciel

Chapitre 3 : Le Test

Responsable du cours :
Dr. Afef Jmal

Année Universitaire : 2020- 2021


77

Sommaire
• Introduction
• Définition du test
• Processus de test simplifié
• Classification des tests
• Difficulté des tests
• Méthodes de tests
▫ Test fonctionnel
▫ Test structurel
78

Introduction

• Il est nécessaire d’assurer la fiabilité des logiciels


▫ Domaines critiques : atteindre une très haute qualité
imposée par les lois/normes/assurances/
▫ Autres domaines : atteindre le rapport qualité/prix jugé
optimal (attentes du client)

• Dans le cycle de vie du logiciel, on assure la fiabilité /


qualité du logiciel par l’activité de Vérification et de
Validation (V&V)
79

Introduction: C’est quoi V&V?


• Vérification
▫ Le développement est-il correct par rapport à la
spécification initiale ?
▫ Est-ce que le logiciel fonctionne correctement?

• Validation
▫ a-t-on décrit le « bon » système ?
▫ est-ce que le logiciel fait ce que le client veut ?
80

Introduction: Méthodes de V&V


• Test statique
▫ Examen ou analyse du texte
▫ Revue de code, de spécifications, de documents de design

• Test dynamique
▫ Exécuter le code pour s’assurer d’un fonctionnement
correct
▫ Exécution sur un sous-ensemble fini de données possibles

• Vérification symbolique
▫ Run-time checking
▫ Exécution symbolique

• Vérification formelle
▫ Preuve ou model-checking d’un modèle formel
▫ Raffinement et génération de code
81

Introduction: Importance du test


• Le test est une activité de V&V dominante et cruciale dans
le monde du logiciel:
▫ Le poids de l’activité du test dans l’industrie du logiciel aux
USA s’élève à plusieurs dizaines de milliards de dollars par
an
▫ En moyenne, le test représente 30% du coût de
développement d’un logiciel standard
▫ Pour un logiciel critique (avionique, nucléaire, médical,
transport), cette part moyenne monte à 50 %
82

Terminologie
• Une faute est la cause adjugée ou supposée d’une erreur

• Une erreur est un écart entre une valeur ou condition


calculée, observée ou mesurée et la valeur ou condition
qui est vraie, spécifiée ou théoriquement correcte.

• Défaillance (failure) est la fin de la capacité d'un système


ou d'un de ses composants d'effectuer la fonction requise,
ou de l'effectuer à l'intérieur de limites spécifiées.

Faute Erreur Défaillance


83

Définitions du test
• Définition de IEEE
« Le test est l’exécution ou l’évaluation d’un système ou d’un composant par des moyens
automatiques ou manuels, pour vérifier qu’il répond à ses spécifications ou identifier les
différences entre les résultats attendus et les résultats obtenus ».
(Standard Glossary of Software Engineering Terminology)

• Le test est une méthode dynamique visant à trouver des bugs


«Tester, c’est exécuter le programme dans l’intention d’y trouver des
anomalies ou des défauts »
G. Myers (The Art of Software testing)
• Le test est une méthode de validation partielle des logiciels

« Tester permet seulement de révéler la présence d’erreurs mais


jamais leur absence. »
E. W. Dijkstra (Notes on Structured Programming, 1972)
84

Objectifs du test
• Le test vise à mettre en évidence les erreurs d’un logiciel

• Le test n’a pas pour objectif de diagnostiquer la cause


des erreurs

• Le test n’a pas pour objectif de corriger les erreurs

• Le test n’a pas pour objectif de prouver la correction


d’un programme

• objectif irréaliste : 0 défaut


85

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Exemples de cas de test
▫ Un tableau de N entiers non redondants
▫ Un tableau vide
▫ Un tableau de N entiers dont 1 est redondant
▫ Etc.
86

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Etape 1 : On définit un cas test (CT) à exécuter, i.e. un
“scénario” que l’on veut appliquer
▫ Un tableau de N entiers non redondants
Cas de test
87

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Etape 2 : On concrétise le cas de test en lui fournissant
les données de test (DT)
▫ Le tableau [1,0,12,4,41,5]
Cas de test

[1,0,12,4,41,5] Données de test


88

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Etape 3 : On indique le résultat que l’on attend pour ce
CT (prédiction de l’Oracle)
▫ [1,0,12,4,41,5] => [0,1,4,5,12,41]
Cas de test

[1,0,12,4,41,5] Données de test



[0,1,4,5,12,41] Prédiction de l’oracle
89

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Etape 4 : On exécute le script de test testant le CT sur
les DT

Cas de test

[1,0,12,4,41,5] Données de test Script de test Résultat [1,0,12,4,41,5]



[0,1,4,5,12,41] Prédiction de l’oracle
90

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Etape 5 : On compare le résultat obtenu avec le résultat
attendu (oracle)

Cas de test

[1,0,12,4,41,5] Données de test Script de test Résultat [1,0,12,4,41,5]



[0,1,4,5,12,41] Prédiction de l’oracle Comparaison
91

Processus de test simplifié


• Tester ?: réaliser une exécution d’un programme pour y
trouver des défauts
• Exemple: soit un programme pour trier un tableau
d’entiers en enlevant les redondances
Interface : int[] mon_tri(int[] vec)
• Etape 6 : On rapporte le verdict final : Pass/Fail,
succès/échec

Cas de test

[1,0,12,4,41,5] Données de test Script de test Résultat [1,0,12,4,41,5]



[0,1,4,5,12,41] Prédiction de l’oracle Comparaison
92

Processus de test simplifié: Résumé


93

Processus de test simplifié: Résumé


94

Classification des tests


95

Classification des tests: le niveau dans le


cycle de développement
• Tests unitaires (ou test de composant): s'assurer que
les composants logiciels pris individuellement sont
conformes à leurs spécifications et prêts à être regroupés.

• Tests d'intégration: s'assurer que les interfaces des


composants sont cohérentes entre elles et que le résultat de
leur intégration permet de réaliser les fonctionnalités
prévues.

• Tests système: s'assurer que le système complet, matériel


et logiciel, correspond bien à la définition des besoins tels
qu'ils avaient été exprimés.
96

Classification des tests: le niveau dans le


cycle de développement
• Tests de recette (Acceptance testing): Test avec des
données clients pour vérifier que le système répond aux
exigences du client

• Test de régression (Regression testing): sont un


sous-ensemble des tests originaux.
▫ Les tests de régression vérifient qu’une modification n’a pas eu
d’effets de bord sur le produit
▫ Les tests de régression sont utiles parce que la ré- exécution de
tous les tests est très coûteuse
97

Classification des tests: le niveau dans le


cycle de développement
• Alpha-test (alpha testing): test effectué en phase de
développement, avant la distribution du produit (→
alpha-versions du produit)

• Bêta-test (beta testing): test effectué après l'alpha-test,


en distribuant le produit (→ des bêta-versions) à un
groupe limité d'utilisateurs avertis
98

Classification des tests


99

Classification des tests: Sélection de


tests
Deux grandes familles de tests

• Test fonctionnel (ou test en boîte noire)


▫ Ne nécessite pas une connaissance de la
structure interne du système
• Test structurel (ou test en boîte blanche)
▫ La structure interne du système doit être
accessible
100

Sélection de tests :Test fonctionnel


101

Sélection des tests :Test fonctionnel

Black-box testing
102

Sélection des tests : Test structurel


103

Sélection des tests: Comparaison (1/2)


Test fonctionnel Test structurel
• (+) taille des spécifications, • (+) description précise,
facilité oracle facilité script de test

• (+) détection plus facilement • (+) détection plus


des erreurs d’omission et de facilement des erreurs
spécification commises

• (- ) spécifications parfois peu • (- ) oracle difficile,


précises, concrétisation manque d’abstraction
des DT
104

Sélection des tests: Comparaison (2/2)


105

Classification des tests


106

Test de performance
107

Test de stress
• Consiste à exciter le système au
delà de ses capacités nominales

• Vise à tester le bon comportement


du système dans les situations de
surcharge ou également à détecter la façon et l'instant
auquel le système échoue dans ce genre de situations

• Exemples de situations extrêmes: dépasser les capacités


de stockage, envoyer un très grand nombre de requêtes à
une base de données, etc.
108

Test de sécurité

• Consiste à tester la vulnérabilité du système à être


pénétré ou attaqué par un autre programme
malveillant

• Vise à tester également si le système est en mesure de


se protéger contre les accès internes ou externes non
autorisés

• Permet aussi de tester si la base de données du


système est accessible depuis l'extérieur ou non
109

Application
Remplir ce tableau

Test Portée Catégorie Exécutant

Unitaire

Intégration

Fonctionnel

Système

Acceptation

Bêta

Régression
110

Application
Test Portée Catégorie Exécutant
Unitaire Petites portions de code blanche Développeur/
source Machine
Intégration Classe/Composant/ Blanche/noire Développeur
service
Fonctionnel Produit Noire Testeur

Système Produit / Noire Testeur


environnement simulé
Acceptation Produit / Noire Client
environnement réel
Bêta Produit / Noire Client
environnement réel
Régression N’importe quel Blanche/ noire N’importe
111

Difficultés du test (1/2)


Le test exhaustif est en général impossible à réaliser
• En test fonctionnel, l’ensemble des données d’entrée est en général
infini ou très grande taille
Exemple : un logiciel avec 5 entrées analogiques sur 8 bits admet 2^40
valeurs différentes en entrée
• En test structurel, le parcours du graphe de flot de contrôle conduit à
une forte explosion combinatoire

=> le test est une méthode de vérification partielle de logiciels


=> la qualité du test dépend de la pertinence du choix des
données de test
112

Difficultés du test (2/2)


Difficultés d’ordre psychologique ou «culturel»
• Le test est un processus destructif : un bon test est un test qui
trouve une erreur

alors que l’activité de programmation est un processus constructif -


on cherche à établir des résultats corrects

• Les erreurs peuvent être dues à des incompréhensions de


spécifications ou de mauvais choix d’implantation

=> L’activité de test s’inscrit dans le contrôle qualité, indépendant


du développement
113

Méthodes de tests

Test fonctionnel Test structurel

• Analyse • Couverture
partitionnelle structurelle
• Test aux limites • Flot de contrôle
• Test combinatoire • Flot de données
• MBT
114

Analyse partitionnelle
• Principe : diviser le domaine des entrées en un nombre
fini de classes tel que le programme réagisse de la même
façon pour toutes les valeurs d’une classe

• But: vise à diminuer le nombre de cas de tests par calcul


de classes d’équivalence
=>évite des tests redondants (si classes bien identifiées)
=> il ne faut tester qu’une valeur par classe !
115

Analyse partitionnelle
116

Analyse partitionnelle
Procédure :
1.Analyser les exigences pour identifier d’une part les
entrées du programme et leurs domaines, et d’autre
part les fonctionnalités réalisées

2.Utiliser cette information pour identifier les classes


d’équivalence des entrées
▫ Sur la base des conditions sur les entrées/sorties
▫ En prenant des classes d’entrées valides et invalides

3. Définir un ou quelques CTs pour chaque classe


117

Analyse partitionnelle: Exemple 1


• Supposons que la donnée à l’entrée est un entier naturel qui doit contenir
cinq chiffres, donc un nombre compris entre 10,000 et 99,999.
• Le partitionnement en classes d’équivalence identifierait alors les trois
classes suivantes (trois conditions possibles pour l’entrée):
a. -----------------------------------------------------------------------------
b. -----------------------------------------------------------------------------
c. -----------------------------------------------------------------------------
• On va alors choisir des cas de test représentatifs de chaque classe, par
exemple, au milieu et aux frontières (cas limites) de chacune des classes:
a. ------------------------------------------------------------------------------
b. ------------------------------------------------------------------------------
c. ------------------------------------------------------------------------------
118

Analyse partitionnelle: Exemple 1


• Supposons que la donnée à l’entrée est un entier naturel qui doit contenir
cinq chiffres, donc un nombre compris entre 10,000 et 99,999.
• Le partitionnement en classes d’équivalence identifierait alors les trois
classes suivantes (trois conditions possibles pour l’entrée):
a. N < 10000
b. 10000 <= N <= 99999
c. N >= 100000
• On va alors choisir des cas de test représentatifs de chaque classe, par
exemple, au milieu et aux frontières (cas limites) de chacune des classes:
a. 0, 5000, 9999
b. 10000, 50000, 99999
c. 100000, 100001, 200000
119

Analyse partitionnelle: Exemple 2


• Soit un programme calculant la valeur absolue d’un entier
à partir d’une entrée au clavier dont le type est une chaîne
de caractères
• Les entrées invalides sont :
▫ Chaine vide
▫ Chaine contenant un espace: exp ("123 137 ")
▫ Chaine qui ne correspond pas à un décimal: exp ("0x", " -
a56", etc.)
• Les entrées valides
▫ Décimal positif: exp ("12334" )
▫ Décimal négatif : exp("-1234" )
120

Analyse partitionnelle: Exemple 2

Il est également utile de voir si l’on accepte des


entrées limites, notamment la chaîne"-0" : avec
les définitions choisies ci-dessus, il s’agit d’une
entrée invalide appartenant à la classe « pas un
décimal ».
121

Test aux limites


• Le test aux limites permet de compléter une analyse
partitionnelle en introduisant des tests dont l’objectif
est de solliciter des entrées se trouvant aux limites
(frontières) des classes d’équivalence.

• De manière générale, identifier et tester les bornes des


domaines des entrées du programme.
122

Test aux limites: exemples


• Pour un domaine de type intervalle d’entiers [a, b] (avec a < b), il
est intéressant de tester
▫ les valeurs invalides a-1; b+1
▫ les valeurs valides a; a+1; b-1; b.

• Pour un domaine de type ensemble fini, il faut sélectionner


▫ l’ensemble vide, des singletons, des paires, et des ensembles avec
beaucoup d’éléments.

• Pour une entrée de type fichier (en lecture), il faut considérer


▫ les cas du fichier vide, inexistant, inaccessible en lecture par
l’utilisateur, et d’un fichier « normal ».
123

Test combinatoire
• Les combinaisons de valeurs de domaines d’entrée donne
lieu à une explosion combinatoire
• Exemple : Options d’une boite de dialogue MS Word
124

Test combinatoire: exemple 1


• Approche pairwise : sélectionner les DTs pour couvrir
toutes les paires de valeurs
• Exemple : 4 variables avec 3 valeurs possibles chacune

OS Réseau Imprimante Application

XP IP HP35 Word

Linux Wifi Canon9000 Excel

Mac X ATM Canon-EX Pwpoint


126

Test combinatoire: Généralisation


• Sur de plus gros exemples avec N variables à M valeurs :
▫ nb combinaisons : MN
▫ nb paires de valeurs : ~ M2 × N(N − 1)/2

• Un test couvre au plus N(N − 1)/2 paires de valeurs

• On peut espérer générer en M2 plutôt que MN


127

Test combinatoire
• L’approche Pairwise se décline avec des triplets, des
quadruplets, …. mais le nombre de tests augmente très vite

• Une dizaine d’outils permettent de calculer les


combinaisons en Pairwise(ou n-valeurs) :
▫ http://www.pairwise.org/default.html
▫ Prise en charge des exclusions entre valeurs des domaines
et des combinaisons déjà testées
▫ Exemple : outil Pro Test

• Problème du Pairwise:
▫ Le choix de la combinaison de valeurs n’est peut-être pas
celle qui détecte le bug …
▫ Le résultat attendu de chaque test doit être fourni
manuellement
128

Test basé modèle (Model Based Testing


(MBT))
• Basé sur les spécifications/les modèles (UML,
automates, chaines de markov)
▫ Test en boîte noire

• Objectif: l’automatisation de l’activité de test


(génération – concrétisation – exécution)
129

Test basé modèle : Processus


130

Méthodes de tests

Test fonctionnel Test structurel

• Analyse • Couverture
partitionnelle structurelle
• Test aux limites • Flot de contrôle
• Test combinatoire • Flot de données
• MBT
131

Méthodes de test structurel


• Le test structurel s’appuie sur l’analyse du code source de
l’application (ou d’un modèle de celui-ci) pour établir les tests
en fonction de critères de couverture

 Basés sur le graphe de flot de contrôle (toutes les


instructions, toutes les branches, tous les chemins, …)
 Basés sur la couverture du flot de données (toutes les
définitions de variables, toutes les utilisations, …)
132

Graphe de flot de contrôle


133

Graphe de flot de contrôle


• C’est un graphe orienté et connexe (N, A, e, s)
▫ e: un sommet entrée(a)
▫ s: un sommet sortie (g)
▫ Un sommet = un bloc d’instructions
▫ Un arc = la possibilité de transfert de l’exécution d’un nœud
à un autre
• Le graphe G1 comprend 4 exécutions possibles qu’on appelle
chemins de contrôle :
▫ β1 = [a, b, d, f, g] NB: le chemin [a, c, d, e, g] est un
▫ β2 = [a, b, d, e, g] chemin de contrôle,
▫ β3 = [a, c, d, f, g] le chemin [b, d, f, g] n’est pas un
chemin de contrôle.
▫ β4 = [a, c, d, e, g]
134

Expression des chemins de contrôle


• Le graphe G1 peut-être exprimé sous forme algébrique
sous la forme suivante :

G1 = abdfg+ abdeg+ acdfg+ acdeg


le signe + désigne le «ou» logique entre chemins.

• Simplification de l’expression de chemins


G1 = a (bdf+ bde+ cdf+ cde) g
G1 = a (b + c) d (e + f) g
135

Calcul de l’expression des chemins


de contrôle
136

Chemins de contrôle avec boucles

G2= abf + ab(cdeb)*f + ab(ceb)*f


G2= ab(cdeb + ceb)*f
137

Expressions de chemins -Exercice

Question :
• Etablir le graphe de flot de contrôle de ce programme
• Fournir l’expression des chemins
138

Graphe de flot de contrôle du programme P3

not
139

Expressions de chemins -Exercice


• Soit le programme P4 suivant :

Question :
• Etablir le graphe de flot de contrôle de ce programme
• Fournir l’expression des chemins
140

Graphe de flot de contrôle du


programme P4
141

Chemin exécutable/non exécutable


• Nb chemins de contrôle =Nb chemins exécutables+Nb
chemins non exécutables

• On dit qu’un chemin est exécutable s’il existe une donnée


de test (DT) qui sensibilise ce chemin

• On dit qu’un chemin est non exécutable si aucune


donnée de test n’est capable de sensibiliser ce chemin.

Sensibiliser un chemin peut parfois être difficile. Trouver


les DTs qui sensibilisent un chemin est un problème
indécidable
144

Couverture sur le flot de contrôle

Tous les
Tous les arcs
nœuds

Tous les
chemins
indépendants
145

Critère de couverture « Tous les


nœuds »
• But : sensibiliser tous les chemins de contrôle qui nous
permettent de visiter tous les nœuds du graphe de
contrôle.
146

Critère de couverture « Tous les nœuds


»: limites
147

Critère de couverture « Tous les


arcs»
• But : sensibiliser tous les chemins de contrôle qui nous
permettent de visiter tous les arcs du graphe de
contrôle.

• Lorsque le critère « tous les arcs » est totalement réalisé,


cela implique que le critère « tous les nœuds » est satisfait
148

Critère de couverture « Tous les arcs»:


limites
149

Critère de couverture « Tous les arcs»:


limites
150

Critère de couverture « Tous les chemins


indépendants»
• Le critère « tous les chemins indépendants » vise à parcourir tous les
arcs dans chaque configuration possible (et non pas au moins une
fois comme dans le critère tous-les-arcs)

• Lorsque le critère « tous les chemins indépendants » est satisfait,


cela implique :
▫ le critère « tous les arcs » est satisfait,
▫ le critère « tous les nœuds » est satisfait.

• Sur le programme P7, l’arc [b-c] est sensibilisé lorsque i > sup à la
fois dans le contexte sum= 0 (la boucle n’est pas activée) et sum ≠0
(la boucle est activée)
151

Critère de couverture des « chemins


indépendants »
« Sélectionner un jeu de test T tel que, lorsqu’on exécute P
sur les d DT, tous les 1-chemins du graphe de flot de
P sont parcourus au moins une fois. »
▫ Chemin = Séquence de nœuds et d’arcs dans le graphe de
flot de contrôle, initiée depuis le nœud de départ jusqu’à
un nœud terminal. (Il peut y avoir plusieurs nœuds
terminaux dans un programme.)

 1-chemin : Chemin parcourant les boucles 0 ou 1 fois.

 Chemin indépendant : (1-)chemin du graphe de flot de


contrôle qui parcourt au moins un nouvel arc par rapport
aux autres chemins définis dans une base B (i.e. ce chemin
introduit au moins une nouvelle instruction non parcourue).
152

Critère de couverture « Tous les chemins


indépendants»
• V(G) (le nombre de Mc Cabe ou nombre cyclomatique) donne
le nombre de chemins indépendants
• Cas 1 : 1 point d’entrée et 1 point de sortie
V(G)=#arcs -#nœuds + 2
• Cas 2: i points d’entrées et s points de sorties
V(G)=#arcs -#nœuds + i+s
• Taux de couverture

Nb chemins indépendants couverts

V(G)
153

Critère de couverture des « chemins


indépendants »
Méthode de sélection des jeux de test

1. Construire le graphe de flot de contrôle (GFC) de P

2. Déterminer la complexité cyclomatique V(G) du GFC

 Constitue une borne supérieure sur le nombre de chemins


nécessaires pour couvrir tous les chemins indépendants du
graphe de flot d’un programme.

3. Définir un ensemble de base B de chemins indépendants dans le


graphe.

4. Construire un jeu de test qui permettra l’exécution de chaque


chemin de l’ensemble B.

Vous aimerez peut-être aussi