Add test part
This commit is contained in:
parent
c42edd72f8
commit
dfc17ad074
1 changed files with 186 additions and 0 deletions
186
content/projet_programmation/6_tests/index.md
Normal file
186
content/projet_programmation/6_tests/index.md
Normal file
|
@ -0,0 +1,186 @@
|
|||
---
|
||||
title: "PdP: les tests"
|
||||
date: 2024-01-24
|
||||
tags: ["tests", "spécification", "validation"]
|
||||
categories: ["Projet de programmation", "Cours"]
|
||||
---
|
||||
|
||||
Les tests logiciels sont partiels, non exhaustifs et souvent approximé. Il se
|
||||
font tout au long du cycle de developpement mais commencent avant les
|
||||
implémentations. Il sont là pour assurer ou réfuter les propriétés du logiciels
|
||||
et renforcer / compléter *une spécification*.
|
||||
|
||||
Une **spécification** est une description abstraite et rigoureuse de
|
||||
fonctionnalités, comportement et services "rendus".
|
||||
|
||||
La *validation d'une spécification* permet de vérifier l'adéquation de celle-ci
|
||||
à ce qui a été dévellopé.
|
||||
|
||||
La *vérification d'une spécification* permet de s'assurer que l'implémentation
|
||||
est correcte et qu'elle fonctionne en rapport avec notre spécification.
|
||||
|
||||
## Validation
|
||||
|
||||
La validation consiste donc à **analyser** si notre spécification reflète bien
|
||||
ce qui est requis (définis dans le cahier de besoin par exemple). D'après
|
||||
Sommerville (2005) ça passe par:
|
||||
|
||||
* Le contrôle de **l'adéquation** avec les parties prenantes;
|
||||
* Le contrôle de **la complétude**, de tout de qui a été réalisé;
|
||||
* Le contrôle de **la consistance**, qu'il n'y a pas de contradiction;
|
||||
* le contrôle de **la faisabilité** de ce qui est à réaliser;
|
||||
* le contrôle de **la vérifiabilité**, que ce qui va être réaliser peut être
|
||||
vérifier.
|
||||
|
||||
Cette vérification est le plus souvent informelle et **non automatisable**
|
||||
(difficilement formalisable, prouvable, quantifiable).
|
||||
|
||||
Cependant plusieurs techniques permettent de valider:
|
||||
|
||||
* La **revue des besoins**;
|
||||
* Le **prototypage**;
|
||||
* La construction de **tests**.
|
||||
|
||||
## Vérification
|
||||
|
||||
Consitste à analyser que l'implementation est bien le reflet de la
|
||||
spécification. Elle prend deux formes:
|
||||
|
||||
* La vérification **formelle** qui implique un contrôle mathematique des
|
||||
propriété par des méthodes formelles et *mathématiques*.
|
||||
* La vérification **pratique** par des test de propriété de notre
|
||||
implementation au regard de sa spécification.
|
||||
|
||||
### Vérification formelle
|
||||
|
||||
elle utilise des langages abstrait de spécification, des outils d'aide à la
|
||||
spécification et à son contrôle, des langages de programmation incluant des
|
||||
éléments de spécification (comme *Agda*, *Idriss*), des outils d'aide à la
|
||||
preuve comme *Coq*, *Isabelle* ou *Lean*.
|
||||
|
||||
Cependant, **toute propriété non triviale d'un programme est indécidable**.
|
||||
Ce qui signifie que la vérification formelle est souvent *difficile*,
|
||||
*fastidieuse* même si elle est vecteur de *progrès*.
|
||||
|
||||
Elle est applique que dans les cas ou la robustesse est une composante crutiale
|
||||
(aéronautique, médical, etc.)
|
||||
|
||||
### Vérification par les tests
|
||||
|
||||
Aussi appelée **vérification pratique**, elle est effectuée par des programmes
|
||||
qui vérifient ou non des propriété de notre implementation. Attention cependant,
|
||||
les tests validés ne signifient pas pour autant que notre programme fonctionne.
|
||||
|
||||
Il sont rarement exhaustifs et exacts.
|
||||
|
||||
La validations d'une batterie de tests ne signifie donc pas que notre programme
|
||||
fonctionne, cependant si l'un d'eux échoue alors notre programme ne fonctionne
|
||||
pas. On audugmente juste la confiance en notre implementation.
|
||||
|
||||
## Non exhaustivité des tests
|
||||
|
||||
Plusieurs facteurs implique la non exhaustivité des tests:
|
||||
|
||||
* La taille et la description des domaines d'entrée;
|
||||
* Les caractéristiques générale de notre logiciel par exemple la complexité,
|
||||
l'ergonomie, la flexibilité, ...;
|
||||
* Les caractéristiques de l'implémentation;
|
||||
* Les ressources affectés aux tests.
|
||||
|
||||
Les tests sont d'autant plus non exhastif qu'ils couvrent beaucoup d'aspects du
|
||||
logiciel comme les performances, la cmplexité, l'ergonomie, la préservation des
|
||||
propriétés après modifications ect. Même **après décomposition** en
|
||||
sous-besoins, ces points sont tout aussi difficiles à tester, par exemple
|
||||
l'*ergonomie*:
|
||||
|
||||
* **l'efficacité** - permettre aux utilisateurs d'atteindre leurs buts;
|
||||
* **la productivité** - minimiser le temps et l'effort nécessaires à
|
||||
l'utilisateur;
|
||||
* **la sûreté de fonctionnement** - limiter les risques pour l'utilisateur;
|
||||
* **La satisfaction**.
|
||||
|
||||
Il est est difficile de décrire toutes les propriété d'un logiciel et donc de
|
||||
produire des tests exhastifs. Mais comme nous l'avons évoqué plus haut, les
|
||||
ressources allouées aus test limitent aussi cette exhastivité (motivatuons des
|
||||
testeurs, temps, moyens humains etc. ).
|
||||
|
||||
### La robustesse d'un programme
|
||||
|
||||
Elle se définie par rapport à la spécification des domaines d'entrée
|
||||
\\(Dom_{OK}\\) pour lesquel le programme doit fonctionner. Les tests positifs
|
||||
sont ceux avec les entrées dans \\(Dom_{OK}\\). Ceux négatifs sont donc ceux
|
||||
pour les entrées hors de \\(Dom_{OK}\\).
|
||||
|
||||
Tester le domaine pour lesquelle le programme fonctionner est déjà compliqué,
|
||||
tester le complementaire à \\(Dom_{OK}\\) l'est encore plus! Mais ces tests sont
|
||||
important.
|
||||
|
||||
### La couverture
|
||||
|
||||
La non-exhaustivité des tests induisent la **couverture** : on tend vers cette
|
||||
exhaustivité, nous avons plusieurs type de couverture aue nous allons détailler.
|
||||
Mais là encore il est très difficile d'atteindre l'exhaustivité.
|
||||
|
||||
#### Les couverture de **code-sources**
|
||||
|
||||
Elle conserne:
|
||||
|
||||
* Le *code sources statiques* qui couvrent les codes sources de tous les
|
||||
composants (les lignes de codes);
|
||||
* Le *code sources dynaniques* qui couvrent le code pendant son exécution.
|
||||
|
||||
Il existe une terminologie spécifique qui se rapporte à la granularité des
|
||||
élements testés :
|
||||
|
||||
* Les *tests unitaires* qui concernent les éléments basiques du code
|
||||
source comme les fonctions ou les méthodes;
|
||||
* Les *test de composants* qui concernent des ensembles d'éléments comme les
|
||||
modules ou des classes. Il sont souvent associés à des *tests d'intégrations*
|
||||
qui vérifient le lien avec les autres élements du code source;
|
||||
* Les *tests systèmes* qui s'appliquent au logiciel.
|
||||
|
||||
#### Les couvertures de **test domaines**
|
||||
|
||||
Il couvrent les domaines d'entrée du programme programme.
|
||||
|
||||
## Les tests autonomes
|
||||
|
||||
Il produit un résultat sous booléene : **passé** / **non passé**. Mais pour
|
||||
fonctionner les tests autonomes soivent contenir tout le necessaire à leurs
|
||||
fonctionnement comme les données. Il sont en général préférables: ils sont
|
||||
utilisables, reproductibles et **facilement utilisables en batterie**.
|
||||
|
||||
Ils peuvent utiliser des assertions au lien de renvoyer `true` ou `false`. Il
|
||||
necessite aussi parfois la création de contextes via les `fixtures setup`. Ces
|
||||
*fixtures* contiennent les opértions d'initialisation, d'ouverture de fichier
|
||||
etc.
|
||||
|
||||
Il est aussi parfois utile de tester avec des composants incomplet ou non
|
||||
implementés ou instanciés, on passe alors pas des *mocks objects*, des *fake
|
||||
objects*, des *dummy objects* ou des *stub*. Tester un composant d'envoi de
|
||||
courriel ne **doit pas vraiment envoyer** de courriels.
|
||||
|
||||
## Tests de non régression
|
||||
|
||||
L'evolution d'un logiciels comporte des risques d'introduire de nouveaux bugs
|
||||
même dans les éléments déjà en place. La progression d'un logicel peut entrainer
|
||||
la regression de son fonctionnement.
|
||||
|
||||
Pour vérifier ces élements, nous pouvons alors créer des **tests de non
|
||||
régression** en géneral mis en batterie pour vérifier la preservation du
|
||||
comportement.
|
||||
|
||||
## Tests en boite blanche / noire
|
||||
|
||||
Les test en **boite noire** [^boitenoire] sont réalisés sans tenir compte de
|
||||
l'implementation mais seulement de son comportement (la spécification). Ceux en
|
||||
**boite blanche** tien compte su caractères particulier de l'implémentation. Et
|
||||
enfin ceux **en boite grise** sont des test en boite noire qui utilisent des
|
||||
hypothèses et / ou informations sur l'implementation.
|
||||
|
||||
Les tests en boite noire peuvent être dédiés à la validation et la vérification
|
||||
de la spécification. Il peuvent être conçus avant même l'implémentation des
|
||||
fonctionnalité testés. Il sont en quelque sorte une extention de la
|
||||
spécification.
|
||||
|
||||
[^boirenoire]: on parle aussi de tests fonctionnels ou tests de recette
|
Loading…
Add table
Add a link
Reference in a new issue