Aller au contenu

Algorithmique · Fiche pratique

Cheatsheet : Tester et expliquer un petit programme

Cas limites, assertions, invariant, terminaison, coût et contrats des mini-projets.

Par · Cours gratuit

Vérifier un programme commence avant son exécution : annoncez ce qu'il accepte et calculez quelques résultats attendus à la main. Cette fiche montre des tests exécutables, un raisonnement d'arrêt et un petit calcul de commande complet.

Un résultat correct sur une entrée ne suffit pas à conclure pour toutes les données. Les tests, la justification du résultat, la terminaison et le comptage du travail répondent à des questions distinctes.

1. Construire des cas de test indépendants

Un cas de test associe une entrée précise à un résultat attendu. Une assertion vérifie une condition et signale un échec si elle est fausse. Les attentes doivent venir du contrat ou d'un calcul indépendant, pas être copiées du programme à vérifier.

Notre fonction reçoit une suite ordonnée de nombres réels finis. Elle compte les valeurs strictement supérieures à zéro, y compris chaque occurrence d'un doublon. Zéro ne compte pas ; une suite vide produit zéro. Ces règles définissent le problème avant son implémentation.

Attentes pour count_positive
EntréeRésultatQuestion couverte
[]0Aucun élément
[0]0Frontière de la positivité
[5]1Un élément retenu
[-2, 0, 3, 3]2Négatif, zéro et deux occurrences positives

2. Exécuter des vérifications explicites

Python fournit assert comme instruction ; MATLAB propose la fonction assert. Un échec interrompt ici le jeu de vérifications et signale que le résultat obtenu ne correspond pas à l'attente. Le message final ne s'affiche que si ces vérifications réussissent.

En MATLAB, la fonction s'enregistre dans count_positive.m et le script de tests dans check_count_positive.m, dans le même dossier. Les assertions Python peuvent être désactivées par certaines options d'exécution : elles ne doivent pas constituer l'unique validation de données externes.

Compter les valeurs positives et tester le résultat

Le parcours ajoute 1 au compteur seulement lorsqu’une valeur vérifie value > 0.

// example.pseudo
// count_positive
FUNCTION count_positive(values)
    count <- 0
    FOR EACH value IN values DO
        IF value > 0 THEN
            count <- count + 1
        END IF
    END FOR
    RETURN count
END FUNCTION

Résultat expliqué. La dernière attente vaut 2 : les deux occurrences de 3 comptent séparément. Le message All tests passed. confirme ces cas précis, pas toutes les entrées possibles.

3. Résultat, arrêt et coût : trois contrôles

Un invariant de boucle est une propriété vraie avant chaque nouveau test. Pour la somme de 1 à n, avant de traiter value, total contient la somme de 1 à value - 1. Initialement value vaut 1 et total vaut 0 : la somme sans terme est bien zéro. Ajouter value puis augmenter value de 1 conserve la propriété.

Une quantité de progression explique l'arrêt. Tant que value <= n, il reste n - value + 1 entiers à traiter. Ce nombre entier diminue de 1 par tour jusqu'à zéro. Pour n = 4, la sortie se fait avec value = 5 et l'invariant donne la somme complète 10.

Un coût n'a de sens qu'avec une convention. Si l'on compte seulement les additions au total, il y en a n. On ne compte pas ainsi les comparaisons, les mises à jour des variables ni une durée en secondes. Une mesure de temps dépendrait aussi du langage et de la machine.

Même boucle, différentes observations
Pour n = 4ValeurInterprétation
Résultat101 + 2 + 3 + 4
Tours du corps4Une valeur ajoutée par tour
Tests value <= n5Le dernier test est faux
Additions au total4Opération choisie pour le coût
Valeur après sortie5Première valeur qui dépasse n

4. Mini-projet : une commande aux règles vérifiables

Le prix unitaire est un entier non négatif en centimes et la quantité un entier non négatif. Une commande vide coûte zéro. Sinon, les frais valent 100 centimes si le sous-total est strictement inférieur à 1 000 centimes, et zéro à partir de 1 000 centimes. Aucun taux de taxe ou remise n'est supposé.

Le seuil de 1 000 centimes et les frais de 100 sont des constantes de la règle choisie. La branche de retour anticipé traite le cas vide avant les frais. Une règle différente peut être valide, mais elle demanderait d'autres résultats attendus.

Calculer le total puis vérifier trois frontières

En MATLAB, enregistrez order_total.m puis use_order_total.m dans le même dossier.

// example.pseudo
// order_total
FUNCTION order_total(price, quantity)
    IF quantity == 0 THEN
        RETURN 0
    END IF
    subtotal <- price * quantity
    delivery <- 0
    IF subtotal < 1000 THEN
        delivery <- 100
    END IF
    RETURN subtotal + delivery
END FUNCTION

Résultat expliqué. Trois articles donnent un sous-total de 750 puis un total de 850 centimes. Quatre articles donnent 1 000 centimes sans frais.

Erreur à éviter. Une entrée hors du contrat et une erreur de calcul ne sont pas la même situation. Ces petits exemples n’effectuent pas une validation complète de tous les types.

Une modification remplace value > 0 par value >= 0 dans count_positive. Quel test existant révèle immédiatement le défaut ?

Le cas [0] doit renvoyer 0. La version modifiée renverrait 1 et ferait échouer cette assertion. Le test de frontière est donc utile même si plusieurs autres exemples réussissent.

Télécharger cette fiche en PDF · Toutes les fiches par thème