Tester ses programmes en Python

Quand tu écris un programme, tu veux être sûr qu’il fonctionne correctement. Un test, c’est un petit bout de code qui vérifie automatiquement qu’une partie de ton programme fait ce que tu attends.

    5ttr 6ttr

Faire des tests, ce n’est pas du temps perdu : c’est une sécurité qui permet de détecter des erreurs rapidement et d’être confiant quand tu modifies ton code.

Ecrire des tests, ça prend du temps. Mais ce temps, ce coût, est gagné et récupéré très rapidement par la suite. Il s'agit d'un investissement.

Ecrire du code et le modifier sans avoir de tests automatiques, c'est un comme si tu travaillais comme cet ouvrier qui peint une ligne blanche sur la route et revient toujours remplir son pinceau au pot de peinture...

peinture

Pourquoi écrire des tests ?

  • Détecter tôt les erreurs : mieux vaut que ton test crashe en 2 secondes que de découvrir le bug pendant un projet complexe.
  • Répétables : un test peut être relancé autant de fois que nécessaire, toujours sur le même jeu de données.
  • Documenter : un test montre clairement ce que ton code est censé produire.
  • Éviter les régressions : si tu améliores ton code, tes anciens tests garantissent que tu n’as rien cassé.

Principe : données maîtrisées → résultats attendus

L’idée est simple :

  1. Tu choisis un jeu de données d’entrée simple et bien connu.
  2. Tu décides du résultat attendu.
  3. Tu écris un test qui exécute ta fonction et compare le résultat obtenu au résultat attendu.

Exemple

Une fonction qui calcule la moyenne d’une liste de nombres :

def moyenne(notes):
    return sum(notes) / len(notes)

👉 Testons-la avec des données maîtrisées :

def test_moyenne():
    notes = [10, 20, 30]
    attendu = 20
    resultat = moyenne(notes)
    assert resultat == attendu, f"Attendu {attendu}, obtenu {resultat}"
  • assert vérifie la condition : si c’est faux, le test échoue.
  • Ici, avec [10, 20, 30], on sait que la moyenne est 20.

Organiser des tests en Python

Option 1 — Tests manuels avec assert

Rapide à écrire, parfait pour débuter.

En Python, l’instruction assert sert à vérifier qu’une condition est vraie pendant l’exécution du programme. Si la condition est fausse, Python déclenche une erreur (AssertionError) et interrompt le programme. C’est un moyen simple de créer des tests rapides:

assert 2 + 2 == 4 # ok
assert 0 + 5 == 5 # ok
assert 0 * 5 == 5 # provoque une erreur

On peut donc aussi comparer le résultat d’une fonction avec la valeur attendue. Exemple :

def addition(a, b):
    return a + b

assert addition(2, 3) == 5   # Passe
assert addition(0, 7) == 7   # Passe
assert addition(2, 2) == 5   # Échoue → AssertionError

En pratique, les tests sont regroupés dans une méthode de test:

def test_addition():
    assert addition(2, 3) == 5   # Passe
    assert addition(0, 7) == 7   # Passe
    assert addition(2, 2) == 5   # Échoue → AssertionError

On peut aussi ajouter un message qui sera affiché en cas d'erreur:

assert 2 == 3, "Devrait être égal"

Résultat:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
AssertionError: Devrait être égal

👉 L’avantage est la simplicité : une seule ligne suffit pour vérifier. Mais l’inconvénient est que les messages d’erreur sont basiques, et on ne peut pas organiser facilement de gros ensembles de tests. C’est pourquoi assert est idéal pour démarrer et tester localement, puis on passe à des frameworks comme unittest ou pytest pour des projets plus grands.

Option 2 — Utiliser pytest (simple et puissant)

pytest étant un module externe, il faut l'installer d'abord:

pip install pytest

Puis écrire des fonctions test_... :

def test_moyenne():
    assert moyenne([10, 20, 30]) == 20
    assert moyenne([5, 15]) == 10

Et lancer (cmd):

pytest

Tu découvriras rapidement qu'il est généralement plus propre de placer les méthodes de test dans un fichier séparé.

Option 3 — Utiliser unittest (librairie standard, mais plus compliquée)

import unittest

class TestMath(unittest.TestCase):
    def test_addition(self):
        self.assertEqual(2 + 2, 4)
        self.assertEqual(0 + 5, 5)

if __name__ == "__main__":
    unittest.main()

Différence entre pytestet unittest?

Bonne question 👍

En Python, tu as donc deux approches principales pour les tests :


unittest (librairie standard)

  • Inclus par défaut avec Python → rien à installer.
  • Fournit une structure claire : classes de test, méthodes, assertions (self.assertEqual, self.assertTrue, etc.).
  • Standard utilisé depuis longtemps → beaucoup de documentation et d’exemples.
  • Compatible avec les environnements scolaires/entreprise où on n’installe pas de paquets externes.

👉 Avantage pédagogique : apprendre les concepts de test sans dépendance supplémentaire.


pytest (librairie externe)

  • Installation : pip install pytest.
  • Beaucoup plus simple à écrire : pas besoin de classes, juste des fonctions test_....
  • Messages d’erreurs très lisibles (il affiche directement l’expression qui a échoué).
  • Permet facilement des tests avancés : fixtures, paramétrisation, mocks.
  • Devenu le standard de fait dans beaucoup de projets pros.

👉 Avantage pratique : moins de code, plus lisible pour débuter et pour des projets réels.


Faut-il apprendre les deux ?

  • Pour des élèves débutants : commencer avec assert puis pytest → plus clair, rapide à mettre en œuvre.
  • Pour des cours “pro” : montrer aussi unittest car il fait partie de la bibliothèque standard, et certains environnements pros (ou examens) exigent de savoir l’utiliser.
  • Les deux peuvent coexister : pytest sait exécuter les tests écrits avec unittest.

✅ En résumé :

  • unittest = robuste, standard, utile si environnement limité.

  • pytest = moderne, lisible, préféré dans les projets actuels.

  • Mieux vaut connaître un peu des deux, mais commencer par pytest rend la découverte plus agréable.


Bonnes pratiques

  • Utiliser des jeux de données petits et clairs (pas besoin de 1000 valeurs pour tester une moyenne).
  • Tester des cas normaux mais aussi des cas limites (ex : liste vide, liste avec un seul élément, valeurs négatives, etc.).
  • Donner des noms explicites aux tests (test_moyenne_vide, test_addition_positifs).
  • Relancer les tests après chaque modification : ils doivent toujours passer.

Exemple concret : tester un algorithme

Imaginons un algorithme qui trouve le maximum d’une liste :

def maximum(liste):
    return max(liste)

Tests :

def test_maximum():
    assert maximum([1, 2, 3]) == 3
    assert maximum([-5, -2, -10]) == -2
    assert maximum([42]) == 42

Ces cas simples et répétables montrent que la fonction marche dans des situations différentes (positifs, négatifs, liste d’un seul élément).


À retenir

  • Les tests permettent de vérifier automatiquement ton code.
  • Ils doivent utiliser des jeux de données maîtrisés pour que le résultat attendu soit clair.
  • Tu peux commencer avec des assert, puis découvrir unittest ou pytest plus tard.
  • Tester ton code, c’est un réflexe de pro qui t’évitera beaucoup de bugs.