Les essentiels de la POO — classes, héritage, méthodes magiques, décorateurs
Le vrai code SDET vit dans des classes — page objects, clients d'API, cas de test de base. Voici les essentiels que vous utiliserez vraiment, sans théorie lourde.
L'idée, en une ligne
Une classe est un plan. À partir d'elle vous fabriquez des objets qui portent leurs propres données et leurs propres actions. Maîtrisez quatre petits morceaux et vous pourrez lire presque n'importe quel framework de test.
Les quatre morceaux
- Classe +
__init__:__init__(self, ...)s'exécute quand vous créez un objet et stocke ses données surself—selfest l'objet lui-même. Les méthodes sont juste des fonctions dont le premier paramètre estself, pour qu'elles puissent lire et modifier les données de cet objet. - Héritage : une classe enfant réutilise un parent.
class ApiTest(BaseTest)obtient tout ce queBaseTesta, etsuper().__init__(...)exécute la configuration du parent avant que l'enfant n'ajoute la sienne. C'est ainsi qu'uneBasePagedonne à chaque page object un driver partagé. - Méthodes magiques : les noms dunder comme
__init__,__repr__,__eq__se branchent sur la syntaxe de Python. Définissez__repr__et votre objet s'affiche utilement dans un assert échoué ; définissez__eq__et==compare par valeur. - Décorateur : enveloppe une fonction pour ajouter un comportement — chronométrage, journalisation, réessais — sans toucher à son corps.
@wrapsdefunctoolscopie le nom et la docstring de l'original pour que les débogueurs et les runners de test voient encore la vraie fonction.
Voyez-le à l'œuvre
▸ try it
import functools
# Decorator that retries a flaky step
def retry(times):
def outer(fn):
@functools.wraps(fn) # keep fn's real name/docstring
def inner(*args, **kwargs):
for attempt in range(times):
try:
return fn(*args, **kwargs)
except AssertionError:
if attempt == times - 1:
raise
return inner
return outer
class BasePage:
def __init__(self, url):
self.url = url
def __repr__(self): # useful in a failed assert
return f"{type(self).__name__}({self.url!r})"
class LoginPage(BasePage):
def __init__(self, url, user):
super().__init__(url) # run parent setup
self.user = user
@retry(times=3)
def submit(self):
assert self.user, "no user set"
return "ok"
print(LoginPage("/login", "amy")) # LoginPage('/login')Lisez-le de haut en bas : BasePage tient une url et s'affiche joliment, LoginPage réutilise cette configuration avec super().__init__ et ajoute un utilisateur, et @retry enveloppe submit pour qu'un assert instable ait quelques essais de plus avant d'échouer.
Avancé — pourquoi chaque morceau mérite sa place
- L'héritage garde la configuration partagée en un seul endroit, pour que chaque page object obtienne le même driver et les mêmes helpers sans copier-coller.
__repr__transforme un assert échoué cryptique en un assert lisible — vous voyez l'objet, pas une adresse mémoire.- Les décorateurs ajoutent des réessais ou du chronométrage autour d'une méthode sans éditer la méthode, et
@wrapsgarde le nom original pour que votre rapport de test pointe encore vers la vraie fonction.
Basé sur la doc Python officielle (classes) et functools
Toutes les leçons de Bootcamp de logique
- Motif 1 — Compter la fréquence des choses
- Motif 2 — Deux pointeurs
- Motif 3 — Fenêtre glissante
- Motif 4 — Arithmétique d'indices & parcours de matrices
- Les essentiels de la POO — classes, héritage, méthodes magiques, décorateurs