Une fonction calcule le tarif d'entrée d'un musée, et trois tests…
Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 11 — Conduire un projet · Ce qui coûte cher
Énoncé
Une fonction calcule le tarif d'entrée d'un musée, et trois tests l'accompagnent.
def tarif(age, adherent):
"""Tarif d'entree, en euros."""
if age < 12:
return 0
if adherent:
return 4
if age >= 65:
return 5
return 8
assert tarif(8, False) == 0
assert tarif(30, True) == 4
assert tarif(30, False) == 8
- Combien la fonction a-t-elle de chemins d'exécution ? Combien sont couverts ?
- Écrire le test manquant.
- Que vaut
tarif(70, True)? Est-ce voulu ? - Une couverture complète des chemins prouve-t-elle que la fonction est correcte ?
Corrigé
1. Quatre chemins, un par return. Les trois tests en couvrent trois : le tarif enfant, le tarif adhérent, le plein tarif. Le quatrième — return 5, le tarif senior non adhérent — n'est atteint par aucun test. Un jeu de tests peut donc paraître complet en n'oubliant qu'une ligne.
2.
assert tarif(70, False) == 5, "senior non adherent"
Il faut à la fois et adherent faux : c'est la conjonction qui manquait, et c'est pourquoi elle échappe à qui teste « un critère à la fois ».
3. tarif(70, True) vaut 4, et non : le test if adherent vient avant le test sur l'âge, et il l'emporte. Est-ce voulu ? On ne peut pas le savoir, parce que la docstring ne le dit pas. Un senior adhérent paie au lieu de : c'est probablement l'intention — l'adhésion doit être avantageuse — mais cela résulte ici de l'ordre des if, c'est-à-dire d'un accident.
La conclusion pratique : compléter la docstring, et ajouter le test qui grave la décision.
assert tarif(70, True) == 4, "l'adhesion prime sur le tarif senior"
4. Non. Couvrir les quatre chemins garantit qu'aucune ligne n'est restée inconnue ; cela ne garantit pas que les seuils sont les bons. Une fonction qui écrirait if age < 11 passerait la couverture complète et resterait fausse pour les enfants de ans. Il faut aussi tester autour des bornes : , , , .
Ce que le chapitre 3 avait déjà dit : « le succès d'un jeu de tests ne garantit pas la correction d'un programme ». La couverture est une mesure de ce que les tests atteignent, jamais de ce qu'ils prouvent. Elle sert surtout par la négative : une couverture incomplète, elle, prouve à coup sûr qu'il manque un test.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.