Tests unitaires avec pytest¶
1. Pourquoi utiliser pytest ?¶
- Framework de test unitaire très populaire en Python.
- Syntaxe simple et expressive.
- Intégration facile avec des outils comme
dealpour le Design by Contract.
2. Installation et configuration¶
Installation¶
(Aucune configuration supplémentaire nécessaire pour commencer !)
3. Structure de base d’un test avec pytest¶
Exemple : Test d’une fonction simple¶
# Dans un fichier `test_exemple.py`
def additionner(a, b):
return a + b
# Test associé (nom du fichier doit commencer par `test_`)
def test_additionner():
assert additionner(2, 3) == 5 # Si l'assertion échoue, pytest signale une erreur
Exécution des tests¶
Sortie attendue :
4. Écrire des tests plus avancés¶
Test avec plusieurs cas¶
def test_additionner_plusieurs_cas():
assert additionner(0, 0) == 0 # Cas limite : zéro
assert additionner(-1, 1) == 0 # Nombres négatifs
assert additionner(1.5, 2.5) == 4 # Nombres flottants
Test avec messages personnalisés¶
def test_additionner_avec_message():
result = additionner(2, 3)
assert result == 5, f"Attendu 5, obtenu {result}" # Message d'erreur clair
5. Fixtures (pour éviter la duplication de code)¶
Exemple : Initialisation commune¶
import pytest
class CompteBancaire:
def __init__(self, solde):
self.solde = solde
def deposer(self, montant):
self.solde += montant
@pytest.fixture
def compte_bancaire():
return CompteBancaire(100) # Solde initial pour tous les tests
def test_deposer(compte_bancaire): # `compte_bancaire` est fourni par la fixture
compte_bancaire.deposer(50)
assert compte_bancaire.solde == 150
def test_retirer(compte_bancaire):
compte_bancaire.solde -= 30
assert compte_bancaire.solde == 70
6. Bonnes pratiques pour pytest¶
Nommage des tests¶
- Utilise
test_nom_fonctionpour les tests unitaires. - Utilise
test_nom_fonction_cas_particulierpour les sous-cas.
Isolation des tests¶
- Chaque test doit être indépendant (pas d’effets de bord entre tests).
- Utilise des fixtures pour partager des ressources.
Tests paramétrés (pour éviter la duplication)¶
import pytest
@pytest.mark.parametrize("a, b, expected", [
(2, 3, 5),
(0, 0, 0),
(-1, 1, 0)
])
def test_additionner_parametre(a, b, expected):
assert additionner(a, b) == expected
7. Exercice pour les étudiants¶
Consigne¶
Écrivez des tests pytest pour la classe CompteBancaire suivante :
class CompteBancaire:
def __init__(self, solde_initial):
self.solde = solde_initial
def deposer(self, montant):
if montant > 0:
self.solde += montant
else:
raise ValueError("Montant doit être positif")
def retirer(self, montant):
if montant <= self.solde and montant > 0:
self.solde -= montant
else:
raise ValueError("Montant invalide")
Tests attendus¶
- Test du dépôt d’un montant valide.
- Test de l’échec d’un dépôt avec un montant négatif.
- Test du retrait d’un montant valide.
- Test de l’échec d’un retrait avec un solde insuffisant.
8. Ressources supplémentaires¶
Résumé final¶
pytestest simple et puissant pour les tests unitaires.- Utilisez
assertpour vérifier les résultats attendus. - Les fixtures évitent la duplication de code.
- Les tests paramétrés permettent de tester plusieurs cas en un seul test.