Activité - Module doctest☘
Dans le chapitre F01, nous avons vu qu'un docstring devait au moins présenter les spécifications de la fonction.
On peut ensuite ajouter un jeu de tests au docstring. Si ces tests sont
présentés comme dans les exemples suivants, Python peut les exploiter
directement grâce au module doctest
.
Exemple n°1 - Tester et corriger un code☘
Dans la page précédente, nous avons établit un plan de test pour la fonct somme_impair(n)
. Cette fonction doit renvoyer la somme des n
premiers entiers impairs consécutifs.
cas | n |
valeur renvoyée attendue |
---|---|---|
aucun | 0 | 0 |
un | 1 | 1 |
plusieurs | 4 | 1+3+5+7 = 16 |
Pour mettre en oeuvre ce plan de test, on rédige le code de la fonction, suivi du programme principal qui contient l'appel au module doctest
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
-
Copiez-collez et exécutez ce code. Tous les tests sont-ils passés ?
Une réponse
Le module signale deux tests qui ne passent pas :
********************************************************************** File "__main__", line 7, in __main__.somme_impair Failed example: somme_impair(1) Expected: 1 Got: 0 ********************************************************************** File "__main__", line 9, in __main__.somme_impair Failed example: somme_impair(4) Expected: 16 Got: 15 ********************************************************************** 1 items had failures: 2 of 3 in __main__.somme_impair ***Test Failed*** 2 failures.
Il y a donc une erreur de logique dans ce code.
-
Dans le cas où des tests ne sont pas passés, corrigez le code pour qu'il ne contienne plus d'erreur de logique.
Une réponse
La boucle n'est pas parcourue
n
fois mais seulementn-1
fois. Il faut donc modifier le paramètre de la fonctionrange()
à la ligne 13 :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
def somme_impair(n): """ n - int, entier strictement positif Sortie: int - somme des n premiers entiers impairs >>> somme_impair(1) 1 >>> somme_impair(4) 16 """ s = 0 for i in range(n): s = s + 2*i+1 return s ##----- Mise en oeuvre des tests -----## if __name__ == "__main__": import doctest doctest.testmod()
Cette fois-ci, les tests passent : rien n'est signalé dans la console.
Exemple n°2 - Concevoir un code☘
On considère la fonction contient_e()
qui prend en paramètre une chaîne de caractères et qui renvoie un booléen de valeur True
si la chaîne contient le caractère 'e'
et False
sinon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
-
Complétez les lignes 5 à 8 du code ci-dessus qui contient deux tests à réaliser dans la console par le module
doctest
.Une réponse
Il faut un test pour lequel la valeur renvoyée est
True
, un autre pourFalse
:1 2 3 4 5 6 7 8 9
def contient_e(mot): """ mot – str Sortie: bool – True si mot contient 'e', False sinon >>> contient_e('abcd') False >>> contient_e('Exemple') True """
-
Complétez la définition de la fonction
contient_e()
afin qu'elle respecte ses spécifications puis testez votre code.Un premier code possible
On parcourt chaque caractère. Dès qu'on en trouve un qui est un
'e'
, on renvoieTrue
.
Si on les a tous parcourus et qu'on n'a trouvé aucun'e'
, alors on renvoieFalse
.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
def contient_e(mot): """ mot – str Sortie: bool – True si mot contient 'e', False sinon >>> contient_e('abcd') False >>> contient_e('Exemple') True """ for carac in mot: if carac == 'e': return True return False ##----- Mise en oeuvre des tests -----## if __name__ == '__main__' : import doctest doctest.testmod()
Un second code possible
L'opérateur
in
est bien plus efficace car il répond directement à cette question :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
def contient_e(mot): """ mot – str Sortie: bool – True si mot contient 'e', False sinon >>> contient_e('abcd') False >>> contient_e('Exemple') True """ return 'e' in mot ##----- Mise en oeuvre des tests -----## if __name__ == '__main__' : import doctest doctest.testmod()