Un cap pour ce chapitre
Ce que vous saurez faire
- Construire des tests normaux et limites.
- Identifier une cause plutôt qu’un symptôme.
- Vérifier une correction sans changer la spécification.
Fixer le contrat avant la correction
Supposons une fonction qui compte les valeurs supérieures ou égales à un seuil. Elle reçoit une liste de nombres, accepte la liste vide et renvoie un entier. Elle ne doit pas modifier la liste. Ces précisions définissent la référence qui permet de reconnaître un défaut.
Sans contrat, remplacer ≥ par > pourrait sembler une correction alors que cela change le besoin. Commencez par écrire une entrée, le résultat attendu et une justification indépendante du programme. Le résultat attendu ne doit pas être calculé par une copie du code que l’on cherche justement à vérifier.
Une fiche de bug peut contenir quatre éléments : entrée minimale, attendu calculé à la main, observation et hypothèse de cause. Ajoutez la version du programme si plusieurs corrections sont essayées. Cette trace courte permet de revenir sur une modification et d’expliquer pourquoi le nouveau test est nécessaire.
Choisir des frontières révélatrices
Pour le seuil dix, les valeurs neuf, dix et onze explorent les trois positions utiles. Une liste vide vérifie l’initialisation ; une liste d’un seul élément révèle certains défauts de bornes ; une valeur située uniquement en dernière position détecte un parcours incomplet.
def compter(valeurs, seuil):
total = 0
for valeur in valeurs:
if valeur >= seuil:
total += 1
return totalUn jeu de tests raisonné couvre des situations différentes. Répéter dix listes où tous les nombres dépassent largement le seuil apporte moins d’information que tester précisément la valeur égale au seuil.
Localiser la première divergence
Une trace compare l’état attendu à l’état observé après chaque étape. Si le total est correct avant la dernière valeur puis incorrect après, on examine la condition ou l’itération correspondante. Cette méthode évite de modifier plusieurs parties au hasard et de créer des défauts supplémentaires.
Les causes typiques comprennent des types incompatibles, des indices hors limites, des conditions non exhaustives, des inégalités mal choisies, des effets de bord et des noms trompeurs. Les flottants demandent aussi de la prudence : une approximation binaire peut rendre une égalité exacte inadaptée. La solution dépend toujours du problème et de sa précision attendue.
Vérifier que la correction tient
Après correction, rejouez le test qui révélait le défaut, puis les autres cas du contrat. Le premier protège contre le retour de l’erreur ; les autres vérifient que la réparation n’a pas cassé des comportements auparavant corrects. Une assertion exprime une propriété que l’on souhaite surveiller, mais elle ne prouve pas toutes les propriétés du programme.
La lisibilité contribue à la fiabilité : noms précis, fonctions courtes avec responsabilités claires et absence de dépendances cachées facilitent les vérifications. Un test réussi constitue une observation, pas une preuve universelle. Pour certaines propriétés, un invariant ou un raisonnement sur tous les cas complète les essais.
Exemple suivi : isoler deux défauts différents
Prenons la liste [0,10,11] et le seuil 10. L’attendu vaut deux. Une condition stricte oublie 10 et renvoie un ; un parcours qui oublie la dernière case oublie 11 et renvoie également un. Le même résultat incorrect ne suffit donc pas à identifier la cause. Le tableau des décisions par indice sépare les versions : la première diverge à l’indice 1, la seconde à l’indice 2.
Pour isoler la condition, utilisez [10,0] : la version stricte renvoie zéro tandis que l’oubli du dernier élément conserve le compte attendu de un. Pour isoler la borne, utilisez [0,11] : la condition stricte compte bien 11, mais le parcours incomplet l’oublie. Ces deux petits tests discriminants apportent davantage qu’une liste longue reproduisant le même total faux. Une correction doit être reliée à cette cause, puis vérifiée sur le contre-exemple initial.
Exemple suivi : passer du test à un invariant
Après le traitement des k premières valeurs, écrivons la propriété : total est le nombre de valeurs supérieures ou égales au seuil parmi ces k valeurs. Avant toute itération, k=0 et total=0 : aucune valeur n’a été traitée. À l’itération suivante, on ajoute un exactement si la nouvelle valeur satisfait la condition. La propriété est ainsi conservée sur le préfixe agrandi.
Quand k atteint la longueur de la liste, ce préfixe est la liste entière : la propriété fournit le résultat demandé. Le parcours borné garantit la terminaison et accepte naturellement la liste vide. Ce raisonnement explique pourquoi initialiser total à -1 serait incorrect même si une correction locale compensait ce décalage sur certains tests. Les essais révèlent des erreurs ; l’invariant relie toutes les itérations à une signification précise de l’accumulateur.
À vous de faire varier les choses
Trouvez le test qui démasque chaque bug
Choisissez une version et une liste de nombres séparés par des virgules. Le tableau compare le traitement à un oracle simple conforme au contrat.
Lire le résultat de l’expérience initiale
Ce test révèle une divergence.
La dernière colonne montre où le comportement s’écarte du contrat.
| Indice | Valeur | À compter selon contrat | Compté par version |
|---|---|---|---|
| 0 | 9 | Non | Non |
| 1 | 10 | Oui | Non |
| 2 | 11 | Oui | Oui |
Un bon test est choisi pour distinguer des comportements, pas seulement pour faire fonctionner le programme.
De la compréhension à l’autonomie
À vous de résoudre
Cherchez d’abord par vous-même. Vérifiez les résultats demandés, utilisez les indices si nécessaire, puis comparez votre méthode à la correction.
Tester l’égalité au seuil
Le contrat compte les valeurs ≥10. Quelle réponse attend-on pour [9,10,11] ? Quel résultat erroné produirait le test strict >10 ?
Indice 1
La valeur dix doit être incluse.
Indice 2
Comparez les cas de frontière.
Comprendre la correction
Le résultat attendu est deux : dix et onze conviennent. La condition stricte ne compte que onze et renvoie un. La présence d’une valeur exactement égale au seuil rend ce test discriminant.
Détecter un parcours incomplet
Un parcours utilise range(len(valeurs)-1). Proposez une liste de longueur deux qui révèle que le dernier élément est oublié, pour un seuil de dix.
Indice 1
Placez la seule valeur admissible en dernière position.
Indice 2
La première doit rester sous le seuil.
Comprendre la correction
[0,10] convient. Le résultat attendu est un, mais le parcours traite seulement l’indice zéro et renvoie zéro. Un test comme [10,0] ne révélerait pas ce défaut particulier parce que la valeur oubliée ne devait pas être comptée.
Refuser une correction qui change le besoin
Pour éviter une erreur sur une liste vide, on décide de renvoyer -1 alors que le contrat demande le nombre de valeurs admissibles. Est-ce cohérent ?
Indice 1
Combien d’éléments satisfait le critère dans une liste vide ?
Indice 2
Une réparation doit respecter le sens de la sortie.
Comprendre la correction
Non, le nombre attendu est zéro. Renvoyer -1 introduit un comportement extérieur au contrat. Il faut corriger l’initialisation ou le parcours afin que le calcul produise zéro naturellement, sauf si un autre contrat explicite définit un code d’erreur.
Combiner essais et raisonnement
Cent tests passent. Peut-on affirmer que tous les cas possibles sont corrects ? Comment renforcer la justification de la boucle de comptage ?
Indice 1
Les entrées possibles dépassent souvent les exemples testés.
Indice 2
Exprimez ce que total représente après un préfixe du parcours.
Comprendre la correction
Les tests ne couvrent pas nécessairement toutes les entrées. Un invariant peut établir qu’après chaque itération, total est le nombre de valeurs admissibles dans la partie déjà parcourue. L’initialisation, la conservation et la fin du parcours relient alors le programme au contrat général.
Problème : séparer deux versions fautives
Le seuil vaut 10. V1 utilise > au lieu de ≥ ; V2 oublie le dernier élément mais utilise ≥. Donnez les comptes attendus et observés sur [10,0], [0,11] et [0,10,11]. Quel test isole chaque bug ? Pourquoi la dernière liste seule ne suffit-elle pas à identifier la cause ?
Indice 1
Examinez ce qui est compté à chaque indice.
Indice 2
Deux chemins incorrects peuvent produire le même entier.
Comprendre la correction
Les attendus sont 1,1,2. V1 donne 0,1,1 ; V2 donne 1,0,1. [10,0] isole la condition stricte, [0,11] isole la borne du parcours. Sur la dernière liste, les deux versions renvoient un pour des raisons différentes : il faut une trace ou d’autres entrées pour localiser le défaut.
Problème : réparer sans masquer
Une fonction compte les valeurs admissibles, mais le programmeur corrige un écart en ajoutant systématiquement 1 au résultat. Montrez l’échec sur une liste vide puis sur une liste ne contenant aucune valeur admissible. Proposez une méthode de correction et un jeu minimal de situations à rejouer.
Indice 1
Le compte peut légitimement être nul.
Indice 2
La réparation doit viser le test ou le parcours, pas la sortie de ce seul exemple.
Comprendre la correction
L’ajout systématique produit 1 au lieu de 0 pour [] et pour [1,2] au seuil 10. Il faut retrouver l’élément mal traité, corriger la condition ou la borne et conserver les tests révélateurs. On rejoue au moins le vide, un singleton égal au seuil, un singleton inférieur, un singleton supérieur et une valeur admissible uniquement en dernière position.
Problème : justifier et tester une nouvelle règle
Le besoin change : compter les valeurs dans l’intervalle fermé [a,b], avec a≤b. Écrivez la condition, définissez un invariant, puis donnez le résultat sur [2,3,5,7,8] pour a=3 et b=7. Quels tests vérifient spécifiquement les bornes ?
Indice 1
Les deux comparaisons doivent être vraies.
Indice 2
Une borne fermée inclut l’égalité aux deux extrémités.
Comprendre la correction
La condition est a≤valeur≤b. Après k valeurs, total compte celles du préfixe appartenant à cet intervalle. Le résultat demandé vaut 3, pour 3,5 et 7. Les singletons [3] et [7] doivent donner un, [2] et [8] zéro ; a=b=5 vérifie un intervalle réduit à une seule valeur. Le contrat explique cette évolution, qui constitue un nouveau besoin et non une correction de l’ancien.
Les erreurs qui méritent un détour
- Modifier plusieurs lignes au hasard.
- Isolez d’abord un contre-exemple et la première divergence.
- Utiliser le programme testé pour produire ses résultats attendus.
- Cela peut reproduire la même erreur dans le test.
La fiche à garder
L’essentiel à retenir
- Un test compare une observation à un attendu indépendant.
- Les frontières et cas vides révèlent des défauts précis.
- Une correction doit préserver le contrat.
Cette notion au bac
Retrouvez ces idées dans un sujet complet, avec des indices, une correction expliquée et des ateliers.
- Bac 2026 · Métropole · Jour 2 : Taquin : corriger le programme et conserver la résolubilité
- Bac 2026 · Asie · Jour 1 : Perceptron : de la somme pondérée à l’apprentissage supervisé
- Bac 2026 · Asie · Jour 2 : Robots : interpréter des commandes et relayer des messages
- Bac 2026 · Polynésie · Jour 2 : Taquin et recherche de texte : deux parcours à ne pas interrompre trop tôt
Le prochain pas
Retrouver le catalogue de Terminale
Ce chapitre s’appuie sur le programme officiel de Terminale (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.
