Un cap pour ce chapitre
Ce que vous saurez faire
- Construire un jeu de tests qui couvre des cas différents
- Localiser une erreur grâce à une trace
- Distinguer test réussi et preuve de correction
Partir du résultat attendu
Avant de lancer le programme, calculez indépendamment ce qu’il devrait produire. Sinon, une réponse plausible risque d’être acceptée sans examen. Pour une recherche dans un tableau, choisissez par exemple une valeur présente au début, au milieu, à la fin et une valeur absente. Si le contrat autorise le tableau vide, testez-le aussi. Chaque test doit comporter l’entrée, le résultat attendu et la propriété qu’il examine. Dix exemples presque identiques peuvent être moins utiles que quatre cas choisis pour mettre en difficulté des parties différentes de l’algorithme.
Une table de tests peut comporter trois colonnes : entrée, résultat attendu et défaut ciblé. Pour une recherche, un tableau d’un élément avec une cible présente examine simultanément le démarrage du parcours et sa borne finale. Le calcul attendu doit rester indépendant de la fonction étudiée.
Reconnaître la famille de l’erreur
Une erreur de syntaxe empêche Python de comprendre le programme : parenthèse oubliée ou indentation incorrecte, par exemple. Une erreur d’exécution apparaît sur un chemin effectivement emprunté : division par zéro, indice hors limites ou opération entre types incompatibles. Une erreur logique peut laisser le programme finir normalement tout en produisant une mauvaise réponse. Le message d’erreur est un indice, pas un verdict sur la cause profonde. Une variable incorrecte peut avoir été calculée plusieurs lignes avant l’endroit où elle déclenche enfin une exception.
Lisez la dernière ligne du message d’erreur pour connaître sa nature, puis remontez la pile d’appels pour repérer votre code. La ligne signalée est le lieu de manifestation du défaut. Elle n’est pas nécessairement celle où une donnée incorrecte a été créée.
Réduire puis suivre le cas qui échoue
Quand un grand exemple échoue, cherchez une entrée plus petite qui conserve le défaut. Pour un maximum initialisé à zéro, le tableau [-4] suffit à montrer le problème ; nul besoin de cent mesures. Suivez alors les variables instruction par instruction et repérez le premier état qui ne correspond plus au raisonnement attendu. Corriger au hasard jusqu’à obtenir le résultat désiré est fragile. Une correction doit être accompagnée d’une explication : ici, zéro ne représente pas un élément initial du tableau et domine à tort toutes les valeurs négatives.
Une réduction utile conserve la propriété qui déclenche le défaut. Pour une recherche oubliant la dernière case, remplacer un grand tableau par un seul élément contenant la cible conserve cette propriété. En revanche, déplacer la cible au début d’un tableau plus long peut faire disparaître le symptôme.
Conserver les tests après la correction
Un test qui reproduit un ancien défaut reste utile après sa résolution : il évite qu’une modification ultérieure le réintroduise. On peut écrire des assertions simples pour automatiser ces vérifications. Il faut aussi conserver les tests qui fonctionnaient auparavant, car une correction locale peut casser un autre cas. Enfin, la réussite d’un jeu fini de tests ne prouve pas à elle seule une fonction sur toutes les entrées. Les tests apportent des observations ; une preuve relie le contrat aux opérations pour couvrir l’ensemble des cas autorisés.
def maximum(tableau):
assert len(tableau) > 0
resultat = tableau[0]
for valeur in tableau:
if valeur > resultat:
resultat = valeur
return resultat
assert maximum([4, 7, 2]) == 7
assert maximum([-4]) == -4
assert maximum([8, 8]) == 8Une modification doit être reliée à une hypothèse explicite : « le parcours exclut la dernière case ». Après la correction, vérifiez le dernier élément, mais aussi l’absence et le premier élément. Cela évite de réparer un exemple en créant une autre erreur de borne.
Construire un diagnostic à partir de la première divergence
Une somme initialise total = 0 dans la boucle, puis ajoute la valeur courante. Sur [2, 5, 1], les résultats observés sont deux, cinq et un, alors que les résultats partiels attendus sont deux, sept et huit. La première divergence apparaît au deuxième élément : le premier passage ne suffisait pas à révéler la remise à zéro.
L’hypothèse porte alors sur la conservation du cumul. Déplacer l’initialisation avant la boucle rétablit cette conservation. Un tableau vide doit donner zéro, et un tableau d’un élément doit donner cet élément. Ces tests couvrent des tailles différentes tout en vérifiant la même signification du total.
Tester des propriétés en complément des exemples
Pour une fonction maximum sur un tableau non vide, on peut vérifier l’appartenance du résultat et sa domination de toutes les valeurs. On peut aussi transformer un exemple : permuter les éléments ne devrait pas changer le maximum ; répéter une valeur existante non plus. Ces relations fournissent des contrôles utiles lorsque le résultat exact est coûteux à calculer.
Elles ne remplacent pas un contrat complet. Une fonction toujours égale à zéro respecte l’invariance par permutation, mais échoue sur presque tous les tableaux. Combinez donc exemples précis, familles contrastées et propriétés pertinentes. Une preuve générale reste un raisonnement supplémentaire sur l’algorithme, même lorsqu’un grand jeu de tests réussit.
À vous de faire varier les choses
Faites échouer ce maximum
Sélectionnez une famille de données et une initialisation. Trouvez un cas où le résultat paraît plausible mais ne respecte pas le contrat.
Lire le résultat de l’expérience initiale
Ce test réussit
Cette exécution est correcte. Essayez une autre famille avant de généraliser.
| Valeur | Comparaison | Maximum conservé |
|---|---|---|
| Initialisation | 0 | |
| 4 | 4 > 0 : true | 4 |
| 7 | 7 > 4 : true | 7 |
| 2 | 2 > 7 : false | 7 |
Le meilleur test n’est pas le plus volumineux : c’est celui qui met à l’épreuve une hypothèse fragile du 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.
Un maximum trop optimiste
Une fonction initialise son maximum à 0, puis le remplace lorsqu’elle rencontre une valeur plus grande. Proposez le plus petit tableau non vide révélant le défaut.
Indice 1
Choisissez une entrée dont le maximum est négatif.
Indice 2
Un seul élément suffit.
Comprendre la correction
Le tableau [-4] suffit. La condition -4 > 0 est fausse, donc la fonction renvoie 0, alors que le seul élément et maximum est -4. On peut initialiser le maximum avec le premier élément d’un tableau non vide. Cette correction respecte le contrat et ne suppose plus que les données sont positives.
La dernière place oubliée
Une recherche parcourt range(len(t) - 1). Parmi [9, 2, 5] avec cible 9, cible 2 ou cible 5, quel test révèle le mieux le défaut ?
Indice 1
Déterminez les indices effectivement parcourus.
Indice 2
La borne de range est exclue.
Comprendre la correction
range(2) parcourt seulement 0 et 1. Le test avec cible 5 révèle donc l’oubli du dernier indice 2. Les recherches de 9 et 2 peuvent réussir malgré le défaut. La correction consiste à parcourir range(len(t)), si l’intention est bien d’examiner toutes les positions.
Classer trois défauts
Classez : parenthèse fermante manquante ; accès t[3] avec t = [1, 2] ; moyenne calculée en divisant la somme par 2 pour tout tableau.
Indice 1
Demandez-vous si le programme peut être compris, puis s’il s’exécute, puis si sa réponse est juste.
Indice 2
Une absence d’exception ne garantit pas une bonne réponse.
Comprendre la correction
La parenthèse manquante est une erreur de syntaxe. L’accès t[3] provoque une erreur d’exécution car seuls les indices 0 et 1 existent. La division systématique par 2 est une erreur logique : elle peut s’exécuter sans exception, mais donne une mauvaise moyenne lorsque le tableau n’a pas deux éléments.
Une fausse preuve
Un élève affirme : « J’ai testé cent tableaux de nombres positifs, mon maximum est correct. » Expliquez la limite et proposez trois familles supplémentaires.
Indice 1
Les cent tests explorent-ils réellement tout le domaine ?
Indice 2
Pensez au signe, à la taille et aux répétitions.
Comprendre la correction
Les tests positifs ignorent notamment les tableaux entièrement négatifs, les tableaux d’un élément et les valeurs répétées. Ces trois familles peuvent révéler des erreurs distinctes. Le nombre de tests ne compense pas l’absence de diversité, et même un jeu varié reste un ensemble d’observations plutôt qu’une preuve pour toutes les entrées.
Localiser la première divergence
Une somme incorrecte sur [3, 4, 2] affiche les totaux 3, 4, 2. Donnez les totaux attendus, repérez le premier passage erroné et proposez une cause. Quel petit test distingue cette version d’une somme correcte ?
Indice 1
Un seul élément peut masquer la remise à zéro.
Indice 2
Le deuxième résultat doit conserver le premier.
Comprendre la correction
Les totaux attendus sont 3, 7 et 9. La première divergence est au deuxième passage. Une réinitialisation dans la boucle explique l’oubli du cumul. Le tableau [3, 4] suffit : il devrait donner sept, alors que le défaut produit quatre. Un seul élément ne permettrait pas de mettre cette erreur en évidence.
Le mauvais diviseur dans une moyenne
Une moyenne divise toujours la somme par 2. Elle réussit sur [3, 7]. Proposez un tableau d’un élément et un tableau de trois éléments qui révèlent le défaut, calculez attendu et obtenu, puis indiquez la correction et sa précondition.
Indice 1
Choisissez des sommes non nulles.
Indice 2
La division correcte utilise le nombre d’éléments.
Comprendre la correction
Pour [6], on attend six et on obtient trois. Pour [2, 4, 6], on attend quatre et on obtient six. Il faut diviser la somme par la longueur du tableau. Le contrat doit prévoir un tableau non vide ou définir séparément le comportement sur le vide, afin d’éviter une division par zéro.
Une suite de tests qui départage trois versions
Trois recherches renvoient un booléen : A parcourt tout le tableau ; B oublie la dernière case ; C renvoie toujours vrai. Pour [4, 7], choisissez deux cibles permettant de distinguer les trois comportements. Expliquez pourquoi une cible 4 seule est insuffisante.
Indice 1
Une cible doit être dans la dernière case et l’autre absente.
Indice 2
Les versions A et B réussissent toutes deux lorsque la première case convient.
Comprendre la correction
Avec la cible sept, A et C renvoient vrai, B renvoie faux. Avec la cible neuf, A et B renvoient faux, C renvoie vrai. Les paires de résultats sont donc différentes pour les trois versions. La cible quatre donnerait vrai partout et ne détecterait aucun des deux défauts.
Les erreurs qui méritent un détour
- Modifier plusieurs choses sans observer
- Changez une cause identifiée, puis relancez le cas défaillant et les tests précédents.
- Calculer le résultat attendu avec le programme testé
- Utilisez un calcul indépendant pour éviter de reproduire le même défaut dans le test.
La fiche à garder
L’essentiel à retenir
- Un test possède une entrée et une réponse attendue.
- Les frontières et les petits contre-exemples sont particulièrement utiles.
- Une correction doit expliquer la cause et préserver les autres cas.
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 · Banque nationale · Sujet 1 : Compression RLE des images en niveaux de gris
- Bac 2026 · Banque nationale · Sujet 2 : Salaires, dictionnaires et biais des k plus proches voisins
- Bac 2026 · Banque nationale · Sujet 3 : Calendrier, années bissextiles et fichier iCalendar
Le prochain pas
Retrouver le catalogue de Première
Ce chapitre s’appuie sur le programme officiel de Première (PDF, nouvel onglet). Les explications et exercices sont proposés pour l’apprentissage.
