Se connecterS'abonner

Chapitre 18

Software Testing

Lecture : 18 minQuiz de 12 questions

# Software Testing ## Objectifs et prérequis Ce chapitre vise à fournir aux élèves de Lower Sixth une compréhension approfondie des concepts fondamentaux du test logiciel, en se concentrant spécifiquement sur les types de tests et le test de module. À l’issue de ce cours, les élèves seront capables de : - Définir le test logiciel et expliquer son importance dans le cycle de vie du développement logiciel (SDLC). - Classer les différents types de tests logiciels selon leur objectif, leur niveau et leur approche. - Décrire le test de module (unit testing), ses objectifs, ses techniques et ses outils courants. - Appliquer les principes du test de module à des exemples concrets, notamment dans des contextes africains et camerounais. - Préparer et structurer une réponse type à une question d’examen sur ces thèmes. **Prérequis** : - Connaissances de base en programmation (au moins un langage comme Python, Java ou C#). - Compréhension du cycle de vie du développement logiciel (SDLC) : analyse, conception, implémentation, test, déploiement, maintenance. - Familiarité avec les concepts de fonction, procédure, classe et interface en programmation orientée objet ou procédurale. --- ## I. Types of software testing ### Contexte Le test logiciel est une activité essentielle du SDLC visant à vérifier qu’un logiciel répond aux exigences spécifiées et à détecter les défauts avant sa mise en production. Dans le système éducatif camerounais anglophone, l’accent est mis sur la compréhension théorique et l’application pratique des principes de test, en lien avec les réalités locales : développement d’applications pour la santé (ex. : suivi des vaccins dans les zones rurales), l’éducation (plateformes d’apprentissage en ligne comme celles utilisées par le MINEDUB), ou l’agriculture (apps de conseil aux petits producteurs). Le test permet de réduire les coûts de correction des erreurs, d’améliorer la fiabilité et de renforcer la confiance des utilisateurs — des enjeux critiques dans des contextes où les ressources sont limitées et où les échecs logiciels peuvent avoir des conséquences sociales ou économiques importantes. ### Définitions et faits clés > **Le test logiciel est un processus d’évaluation systématique visant à vérifier qu’un logiciel satisfait aux exigences fonctionnelles et non fonctionnelles, et à identifier les écarts entre le comportement attendu et le comportement réel.** Cette définition s’appuie sur les normes internationales comme l’ISO/IEC 29119 et le ISTQB Foundation Level syllabus, largement adoptés dans les programmes africains de TIC. Les tests logiciels sont classés selon plusieurs critères : - **Niveau** : test de module, test d’intégration, test système, test d’acceptation. - **Objectif** : test fonctionnel, test non fonctionnel (performance, sécurité, ergonomie). - **Approche** : test boîte noire, test boîte blanche, test boîte grise. - **Exécution** : test manuel, test automatisé. ### Types de tests selon l’objectif #### Tests fonctionnels Vérifient que le logiciel effectue les fonctions spécifiées dans le cahier des charges. - *Exemple camerounais* : Une application de déclaration d’impôts développée par une startup de Douala doit correctement calculer la TVA sur les achats selon les taux en vigueur (19,25 % en 2024). Un test fonctionnel vérifierait que pour un achat de 10 000 FCFA, le système retourne 1 925 FCFA de TVA. - *Types* : test de unité, test d’intégration, test système, test de régression, test d’acceptation utilisateur (UAT). #### Tests non fonctionnels Évaluent des attributs comme la performance, la sécurité, la facilité d’utilisation ou la portabilité. - *Exemple africain* : Une plateforme de télémédecine utilisée au Kenya et au Cameroun doit supporter 500 utilisateurs simultanés sans dépasser 2 secondes de temps de réponse. Un test de charge (type de test non fonctionnel) mesurerait cette capacité. - *Types* : test de performance, test de charge, test de stress, test de sécurité, test d’ergonomie, test de portabilité. ### Types de tests selon l’approche #### Test boîte noire Le testeur ne connaît pas la structure interne du code ; il se base uniquement sur les spécifications fonctionnelles. - *Avantage* : indépendant de l’implémentation, adapté aux testeurs non techniques. - *Limite* : ne peut pas détecter les défauts internes comme les boucles infinies ou les chemins de code non testés. - *Technique* : équivalence des classes, analyse des valeurs limites, tables de décision, transitions d’état. - *Exemple* : Tester un formulaire d’inscription à une bourse nationale (ex. : Bourse d’Excellence du MINESUP) en entrant des valeurs valides et invalides pour l’âge (ex. : 16 ans = valide, 15 ans = invalide, 26 ans = invalide si la limite est 25). #### Test boîte blanche Le testeur examine la structure interne du code pour concevoir des cas de test couvrant les chemins, les branches et les conditions. - *Avantage* : permet une couverture élevée du code, détecte les défauts structurels. - *Limite* : nécessite des compétences en programmation, coûteux en temps. - *Technique* : couverture des instructions, couverture des branches, couverture des chemins, couverture des conditions. - *Exemple* : Dans une fonction qui détermine si un étudiant est éligible à une bourse selon sa moyenne (≥ 12/20) et son origine géographique (zones rurales prioritaires), un test boîte blanche vérifierait toutes les combinaisons de ces deux conditions. #### Test boîte grise Combinaison des deux approches : le testeur connaît partiellement la structure interne (ex. : architecture, schéma de base de données) mais teste principalement via l’interface. - *Utilité* : particulièrement adapté aux tests d’intégration et de sécurité. - *Exemple* : Tester une API de paiement mobile (ex. : MTN Mobile Money intégrée à une app de commerce électronique camerounaise) en connaissant les endpoints mais sans voir le code interne de la logique de validation des transactions. ### Tableau comparatif : Types de tests selon l’objectif et l’approche | Critère | Test fonctionnel | Test non fonctionnel | |--------|------------------|----------------------| | **Objectif** | Vérifier ce que le logiciel fait | Vérifier comment le logiciel le fait | | **Exemples** | Calcul correct, flux de connexion | Temps de réponse, résistance aux attaques | | **Techniques** | Équivalence des classes, scénarios utilisateurs | Test de charge, scan de vulnérabilités | | **Outils courants** | Selenium, JUnit, TestComplete | JMeter, LoadRunner, OWASP ZAP | | **Exemple camerounais** | App de déclaration de naissance : champ « nom » accepte seulement lettres et tirets | App de santé communautaire : supporte 1000 requêtes/min sans crash | ### Vocabulaire à retenir - **Test fonctionnel** : Vérifie la conformité aux exigences fonctionnelles. - **Test non fonctionnel** : Évalue les attributs de qualité (performance, sécurité, etc.). - **Test boîte noire** : Test basé sur les spécifications, sans connaissance du code interne. - **Test boîte blanche** : Test basé sur la structure interne du code. - **Test boîte grise** : Approche hybride combinant connaissance partielle du code et test externe. - **Cas de test** : Ensemble de conditions ou de variables sous lesquelles un testeur déterminera si une application fonctionne correctement. ### Exemple de sujet type examen avec plan **Sujet** : *Une ONG basée à Yaoundé développe une application mobile permettant aux agriculteurs de recevoir des conseils sur les cultures adaptées à leur région selon les données météorologiques. Expliquez les différents types de tests logiciels qui devraient être appliqués à cette application, en justifiant votre choix pour chaque type. Donnez un exemple concret de test pour chaque catégorie mentionnée.* **Plan attendu** : **I. Introduction** - Définir le test logiciel et son rôle dans la qualité du produit. - Présenter brièvement l’application cible (conseils agricoles). **II. Tests fonctionnels** - Objectif : vérifier que l’application fournit les conseils corrects selon les données météo et la région. - Exemple : Test de unité sur la fonction qui traduit un code de région (ex. : « Littoral ») en conseils de culture (ex. : « plantain, maïs »). - Technique : équivalence des classes (tester régions valides/invalides, données météo extrêmes). **III. Tests non fonctionnels** - Objectif : s’assurer que l’application est rapide, sécurisée et accessible même avec une connexion faible. - Exemple : Test de charge pour vérifier que l’application supporte 200 utilisateurs simultanés pendant les heures de pointe (6h–8h). - Technique : simulation de trafic avec JMeter. **IV. Approches de test** - Boîte noire : tester l’interface utilisateur (ex. : sélection de région, affichage des conseils) sans connaître le code. - Boîte blanche : vérifier la logique interne de la fonction de recommandation (ex. : couverture des branches si température > 30°C AND pluviométrie < 500mm → conseiller sorgho). - Boîte grise : tester l’API météo externe (ex. : vérifier que l’app reçoit bien les données de l’Agence Nationale de la Météorologie) en connaissant le format JSON attendu mais pas le code interne du serveur. **V. Conclusion** - Souligner que la combinaison de ces tests garantit une application fiable, utile et adoptée par les agriculteurs camerounais, réduisant ainsi les risques d’échec technologique dans un contexte de ressources limitées. --- ## II. Module testing ### Contexte Le test de module (ou test unitaire, *unit testing*) est le premier niveau de test dans le SDLC, effectué dès que un module (fonction, procédure, classe ou méthode) est implémenté. Il vise à vérifier que chaque composant individuel du logiciel fonctionne correctement de manière isolée. Dans le système éducatif camerounais anglophone, l’accent est mis sur la compréhension de cette pratique comme fondement de la qualité logicielle, notamment dans les projets de développement locaux où les équipes sont souvent petites et où la détection précoce des défauts évite des coûts de correction élevés plus tard dans le cycle. Des exemples concrets incluent les fonctions de calcul dans les systèmes de gestion scolaire (ex. : moyenne des élèves), les modules de validation dans les apps de santé publique (ex. : vérification de l’âge pour la vaccination), ou les algorithmes de tri dans les outils agricoles (ex. : classement des récoltes par qualité). ### Définition et objectifs > **Le test de module est une pratique de test logiciel où les unités individuelles de code (fonctions, méthodes, classes) sont testées de manière isolée pour vérifier qu’elles produisent la sortie attendue pour des entrées données, en utilisant des stubs ou des mocks pour simuler les dépendances externes.** Cette définition reflète les bonnes pratiques du ISTQB et des méthodologies Agiles largement promues dans les formations TIC en Afrique. **Objectifs principaux** : - Détecter les défauts tôt dans le cycle de développement (coût de correction jusqu’à 100 fois moindre qu’en phase de maintenance). - Faciliter la maintenance et le refactoring en fournissant une sécurité lors des modifications. - Améliorer la conception du code en encourageant le découplage et la testabilité. - Servir de documentation vivante sur le comportement attendu des unités de code. ### Caractéristiques clés - **Isolation** : Le module testé doit être séparé de ses dépendances (bases de données, fichiers, services externes) à l’aide de *stubs* (implémentations simplifiées) ou de *mocks* (objets qui simulent le comportement et vérifient les interactions). - **Automatisation** : Les tests de module sont généralement écrits dans le même langage que le code de production et exécutés automatiquement à chaque build (ex. : via des outils comme JUnit, NUnit, pytest). - **Répétabilité** : Ils doivent produire le même résultat à chaque exécution, indépendamment de l’environnement. - **Lisibilité** : Les noms des tests doivent clairement indiquer ce qui est testé et quel comportement est attendu (ex. : `test_calculate_tax_returns_zero_for_income_below_threshold`). - **Indépendance** : Chaque test doit être autonome ; l’échec d’un test ne doit pas affecter les autres. ### Techniques de conception de tests de module #### Couverture du code Mesure dans quelle mesure le code source est exécuté par les tests. - **Couverture des instructions** : Chaque ligne de code est exécutée au moins une fois. - *Exemple* : Dans une fonction `if (score >= 12) { return "Pass"; } else { return "Fail"; }`, tester les deux branches couvre 100 % des instructions. - **Couverture des branches** : Chaque branche de chaque structure de contrôle (if, else, switch, boucle) est exécutée au moins une fois. - *Exemple* : Pour `if (age >= 18 && isCitizen)`, tester les combinaisons : (vrai, vrai), (vrai, faux), (faux, vrai), (faux, faux). - **Couverture des chemins** : Chaque chemin possible à travers le code est exécuté au moins une fois. - *Attention* : Peut être exponentiel (ex. : n décisions binaires → 2ⁿ chemins). Souvent limité aux chemins réalistes. - **Couverture des conditions** : Chaque condition booléenne est évaluée à vrai et à faux au moins une fois. - *Exemple* : Dans `(A && B)`, tester A=true/B=false, A=false/B=true, A=true/B=true, A=false/B=false. #### Bonnes pratiques - **Nommez les tests clairement** : Utilisez la convention `given_when_then` ou `test_[méthode]_[condition]_[résultat attendu]`. - *Exemple* : `test_calculate_discount_returns_10_percent_when_amount_over_10000`. - **Un assert par test** : Idéalement, chaque test vérifie un seul comportement pour faciliter le débogage. - **Testez les cas limites** : Zéro, valeurs négatives, maximum autorisé, valeurs vides. - *Exemple camerounais* : Tester une fonction qui calcule le prix d’un sac d’engrais avec remise : quantité = 0, 1, 100 (seuil de remise), 101. - **Évitez la logique complexe dans les tests** : Les tests doivent être simples et prévisibles. - **Exécutez-les fréquemment** : Dans un pipeline CI/CD (Intégration Continue/Déploiement Continu), même sur des machines modestes comme celles utilisées dans les lycées techniques camerounais. ### Outils courants de test de module | Langage | Outil populaire | Caractéristiques clés | |---------|-----------------|------------------------| | Java | JUnit 5 | Annotations (@Test, @BeforeEach), assertions riches, extensions pour les mocks (Mockito) | | Python | pytest | Syntaxe simple, découverte automatique des tests, support des fixtures, riche écosystème de plugins | | C# | NUnit / xUnit.net | Intégration avec Visual Studio, support des tests paramétrés, bonnes performances | | JavaScript | Jest | Mocks intégrés, couverture de code intégrée, idéal pour React/Node.js | | PHP | PHPUnit | Standard dans l’écosystème PHP, support des données de test et des mocks | > **Dans un contexte camerounais, où les ressources peuvent être limitées, des outils gratuits et open-source comme pytest (Python) ou JUnit (Java) sont fortement recommandés pour les projets scolaires et les startups locales, car ils ne nécessitent pas de licence coûteuse et bénéficient d’une large communauté de soutien.** ### Exemples concrets (camerounais et africains) #### Exemple 1 : Fonction de calcul de la taxe sur la valeur ajoutée (TVA) *Contexte* : Une startup de Douala développe une app de facturation pour les PME. ```python def calculate_vat(amount: float, rate: float = 0.1925) -> float: """Calcule la TVA à appliquer sur un montant donné.""" if amount < 0: raise ValueError("Amount cannot be negative") return amount * rate ``` **Tests de module (pytest)** : ```python def test_calculate_vat_positive_amount(): assert calculate_vat(10000) == 1925.0 def test_calculate_vat_zero_amount(): assert calculate_vat(0) == 0.0 def test_calculate_vat_negative_amount_raises_error(): with pytest.raises(ValueError): calculate_vat(-1000) def test_calculate_vat_custom_rate(): assert calculate_vat(5000, 0.05) == 250.0 # Taux réduit pour certains produits ``` #### Exemple 2 : Validation de l’âge pour la vaccination infantile *Contexte* : Une app utilisée par les agents de santé dans les régions du Nord et de l’Est pour suivre le calendrier vaccinal élargi (EVAC). ```java public class VaccinationEligibility { public static boolean isEligibleForMeaslesVaccine(int ageInMonths) { return ageInMonths >= 9 && ageInMonths <= 24; } } ``` **Tests de module (JUnit 5)** : ```java @Test void testEligibleAtMinimumAge() { assertTrue(VaccinationEligibility.isEligibleForMeaslesVaccine(9)); } @Test void testEligibleAtMaximumAge() { assertTrue(VaccinationEligibility.isEligibleForMeaslesVaccine(24)); } @Test void testNotEligibleBelowMinimumAge() { assertFalse(VaccinationEligibility.isEligibleForMeaslesVaccine(8)); } @Test void testNotEligibleAboveMaximumAge() { assertFalse(VaccinationEligibility.isEligibleForMeaslesVaccine(25)); } ``` #### Exemple 3 : Fonction de tri des récoltes par qualité (Kenya/Cameroun) *Contexte* : Une coopérative agricole utilise une app pour classer les récoltes de maïs selon leur teneur en humidité (critère : <14% = bonne qualité, ≥14% = à rejeter). ```python def is_good_quality(moisture_content: float) -> bool: """Retourne True si la teneur en humidité indique une bonne qualité.""" return moisture_content < 14.0 ``` **Tests de module** : ```python def test_is_good_quality_below_threshold(): assert is_good_quality(13.9) == True def test_is_good_quality_at_threshold(): assert is_good_quality(14.0) == False # Limite exclusive def test_is_good_quality_above_threshold(): assert is_good_quality(14.1) == False def test_is_good_quality_negative_input(): assert is_good_quality(-1.0) == False # Valeur absurde, mais fonction doit gérer ``` ### Tableau récapitulatif : Bonnes pratiques du test de module | Pratique | Description | Avantages | |---------|-------------|-----------| | **Isolation** | Utiliser stubs/mocks pour éliminer les dépendances externes | Tests rapides, fiables, reproductibles | | **Nommage explicite** | `test_[méthode]_[scénario]_[résultat]` | Lisibilité, maintenance facile | | **Un assert par test** | Un seul comportement vérifié par test | Débogage simplifié | | **Cas limites** | Tester 0, valeurs négatives, seuils, vides | Détection des erreurs de bordure | | **Exécution fréquente** | Intégrer dans le pipeline CI/CD | Détection précoce des régressions | | **Couverture ciblée** | Viser 80%+ de couverture des branches | Équilibre entre effort et qualité | ### Exemple de sujet type examen avec plan **Sujet** : *Une école secondaire de Buea développe un système de gestion des notes permettant aux enseignants de saisir les évaluations et de calculer automatiquement la moyenne trimestrielle d’un élève. La fonction `calculate_average` prend en entrée une liste de notes (sur 20) et retourne la moyenne. Expliquez comment vous concevriez les tests de module pour cette fonction, en détaillant les cas de test à inclure, les techniques de couverture utilisées, et les outils que vous choisiriez dans un contexte camerounais où les ressources sont limitées.* **Plan attendu** : **I. Introduction** - Définir le test de module et son rôle dans la qualité du logiciel éducatif. - Présenter la fonction `calculate_average` : entrée = liste de floats (notes sur 20), sortie = float (moyenne), hypothèse : liste non vide, notes entre 0 et 20. **II. Cas de test à inclure** - **Cas normal** : Liste avec des notes variées (ex. : [10, 12, 14] → moyenne 12,0). - **Cas limite inférieur** : Liste contenant la note minimale possible (0). - *Exemple* : [0, 0, 0] → moyenne 0,0. - **Cas limite supérieur** : Liste contenant la note maximale possible (20). - *Exemple* : [20, 20, 20] → moyenne 20,0. - **Liste avec une seule note** : Vérifier que la fonction fonctionne avec un élément. - *Exemple* : [15] → moyenne 15,0. - **Liste vide** : Attendre une exception (ex. : `ValueError`) car la moyenne d’aucune note est indéfinie. - **Notes négatives** : Attendre une exception (les notes ne peuvent pas être négatives). - **Notes supérieures à 20** : Attendre une exception (hors échelle). - **Somme entraînant une précision flottante** : Vérifier l’arrondi ou l’acceptation d’une petite tolérance (ex. : [1, 1, 1] → 1,0 ; [1, 1, 2] → 1,333... → comparer avec 1,33 dans une marge de 0,01). **III. Techniques de couverture utilisées** - **Couverture des instructions** : S’assurer que chaque ligne de la fonction est exécutée (ex. : boucle de somme, division, vérification de liste vide). - **Couverture des branches** : Tester les deux branches de la condition `if len(notes) == 0` (liste vide vs non vide). - **Couverture des conditions** : Si la fonction vérifie chaque note individuellement (ex. : `if note < 0 or note > 20`), tester chaque partie de la condition à vrai et faux. - *Justification* : Dans un contexte de ressources limitées, viser la couverture des branches offre un bon équilibre entre effort de test et détection de défauts critiques. **IV. Outils choisis** - **Langage** : Python (choisi pour sa simplicité, sa gratuité et son utilisation croissante dans les lycées techniques camerounais). - **Outil** : `pytest` (open-source, léger, pas de configuration lourde, supporte les fixtures et la découverte automatique des tests). - *Alternative* : `unittest` (bibliothèque standard de Python) si l’environnement ne permet pas l’installation de paquets externes, bien que moins convivial. - **Justification** : Dans les établissements scolaires camerounais où les budgets logiciels sont restreints, des outils gratuits et soutenus par une communauté active sont essentiels. `pytest` permet d’écrire des tests lisibles et maintenables avec peu de formation. **V. Conclusion** - Souligner que une batterie de tests de module bien conçue permet de détecter tôt les erreurs de logique (ex. : division par zéro, mauvaise gestion des limites), réduisant ainsi les risques de notes incorrectes pouvant affecter l’orientation des élèves. - Insister sur le fait que dans un contexte éducatif camerounais, où la confiance dans les systèmes scolaires est primordiale, la qualité logicielle passe par des pratiques comme le test de module, même avec des moyens modestes. --- ## Synthèse du chapitre - Le test logiciel est un processus systématique de vérification et de validation visant à garantir la qualité, la fiabilité et la conformité d’un logiciel aux exigences. - Les tests sont classés selon l’objectif (fonctionnel vs non fonctionnel), l’approche (boîte noire, blanche, grise) et le niveau (module, intégration, système, acceptation). - Les tests fonctionnels vérifient *ce que* le logiciel fait (ex. : calculs, flux utilisateurs) ; les tests non fonctionnels évaluent *comment* il le fait (ex. : performance, sécurité). - Le test de module (unit testing) est le premier niveau de test, effectué sur des unités de code isolées pour vérifier leur comportement correct. - Il repose sur l’isolation (stubs/mocks), l’automatisation, la répétabilité, la lisibilité et l’indépendance des tests. - Les techniques de conception incluent la couverture des instructions, des branches, des chemins et des conditions, avec un bon équilibre entre effort et efficacité. - Dans un contexte camerounais et africain, l’utilisation d’outils ouverts et gratuits (pytest, JUnit) est fortement recommandée pour assurer l’accessibilité et la durabilité des projets logiciels locaux. - Les bonnes pratiques (nommage clair, un assert par test, tests des cas limites) améliorent la maintenabilité et la fiabilité du code. - Le test de module permet de détecter les défauts tôt, réduisant considérablement les coûts de correction et renforçant la confiance dans les systèmes développés localement (santé, éducation, agriculture). ---

Quiz du chapitre

12 questions — vérifie chaque réponse pour voir l'explication.

  1. 1. What is the primary purpose of unit testing in software development?
  2. 2. Which of the following best describes black-box testing?
  3. 3. In the V-model of software testing, which testing level corresponds to the system design phase?
  4. 4. Which testing technique involves executing the same test case with multiple sets of input data to validate different outcomes?
  5. 5. A developer writes a function to calculate the area of a rectangle. Which test case would best verify the function handles invalid input correctly?
  6. 6. During integration testing, two modules are found to have incompatible data formats when exchanging information. Which type of defect is this most likely classified as?
  7. 7. Which of the following is a key characteristic of exploratory testing?
  8. 8. A test team is designing test cases for a login system. They identify that valid usernames are 6–12 alphanumeric characters. Which technique is most appropriate to reduce the number of test cases while maintaining coverage?
  9. 9. In a software project, the test plan specifies that 80% of requirements must be covered by test cases. After testing, 75% of requirements are covered. What is the most appropriate conclusion?
  10. 10. Which statement correctly describes the difference between validation and verification in software testing?
  11. 11. A test case is designed to check whether a system correctly handles a user session timeout after 15 minutes of inactivity. Which testing technique is most directly associated with this scenario?
  12. 12. In a safety-critical avionics system, which testing approach is most likely to be mandated by regulatory standards such as DO-178C?