LyCode Lab

Chapitre 6 : Spécification, assert, jeux de tests

Spécifier et tester une fonction

Une fonction sans mode d'emploi, c'est un piège : que reçoit-elle ? que renvoie-t-elle ? que se passe-t-il si on lui donne n'importe quoi ? Spécifier une fonction, c'est répondre à ces questions avant de l'écrire. La tester, c'est vérifier qu'elle respecte sa spécification. Dans ce chapitre, tu apprends les deux.

Au programme de NSI : Langages et programmation : Spécification, mise au point de programmes. Prototyper une fonction. Décrire les préconditions sur les arguments. Décrire des postconditions sur les résultats. Utiliser des jeux de tests.

Spécifier une fonction

La spécification d'une fonction tient en quelques éléments : son nom et ses paramètres (le prototype), ce qu'elle fait, les préconditions (ce que les arguments doivent vérifier pour qu'elle marche) et les postconditions (ce que le résultat garantit). On l'écrit dans une docstring, un texte entre triples guillemets juste sous la ligne def.

Une fonction spécifiée
def moyenne(valeurs):
    """Renvoie la moyenne arithmétique des éléments de valeurs.

    Précondition : valeurs est un tableau de nombres non vide.
    Postcondition : le résultat est compris entre le plus petit
    et le plus grand élément de valeurs.
    """
    return sum(valeurs) / len(valeurs)

help(moyenne)

Vérifier une précondition avec assert

Écrire la précondition dans la docstring ne protège pas la fonction. L'instruction assert condition, message vérifie la condition à l'exécution : si elle est fausse, le programme s'arrête avec une AssertionError et ton message. On détecte ainsi un mauvais appel tout de suite, et pas trois fonctions plus loin.

Une précondition vérifiée
def moyenne(valeurs):
    assert len(valeurs) > 0, "la liste ne doit pas être vide"
    return sum(valeurs) / len(valeurs)

print(moyenne([2, 4]))
print(moyenne([]))

Un jeu de tests

Un test compare le résultat d'un appel à la valeur attendue : assert moyenne([2, 4]) == 3. Un jeu de tests en rassemble plusieurs. Leur qualité compte plus que leur nombre : il faut des cas typiques, des cas limites (liste vide, un seul élément, valeurs négatives, valeur en première ou en dernière position) et des cas d'erreur.

Un petit jeu de tests
def plus_grand(l):
    m = l[0]
    for v in l:
        if v > m:
            m = v
    return m

assert plus_grand([3, 9, 2]) == 9
assert plus_grand([9, 3, 2]) == 9
assert plus_grand([2, 3, 9]) == 9
assert plus_grand([-4, -1, -9]) == -1
assert plus_grand([5]) == 5
print("tous les tests passent")

À toi de jouer : Exercice guidé

La fonction moyenne est spécifiée : sa précondition est que valeurs n'est pas vide. Ajoute une ligne assert qui vérifie cette précondition avec un message. Un appel moyenne([]) doit alors lever une AssertionError.

Passer à l'énigme : Le contrôle qualité