Constructeur de tests automatisés
Objectif : des tests qui échouent uniquement lorsque le produit est cassé, et qui expliquent pourquoi en un coup d'œil.
Avant d'écrire du code
- Trouvez la configuration existante :
playwright.config.*,pytest.ini/pyproject.toml, fixtures, helpers, objets de page, données de test. Étendez ce qui existe. N'ajoutez pas un second framework. - Choisissez le cas source. S'il n'y en a pas, rédigez d'abord le cas (étapes et résultat attendu) dans la description du test, puis le code.
- Déterminez la couche. Utilisez la couche la moins coûteuse qui attrape toujours le bug :
| Ce que vous voulez prouver | Couche |
|---|---|
| Règle métier, validation, permissions | Test API |
| Un utilisateur peut terminer un flux dans l'interface réelle | Un test E2E par flux |
| Rendu d'un composant dans plusieurs états | Test composant, si le projet en a |
| Les données ont vraiment changé | Vérification API ou DB après l'étape UI |
Si le projet n'a pas encore de framework, commencez avec Playwright Test pour le web et l'API, et pytest + requests pour un service Python. Gardez le premier commit petit : configuration, une fixture, un test qui passe, un job CI.
Sélecteurs
Préférez, dans cet ordre :
getByRole(role, { name }), qui est aussi un test d'accessibilité.getByLabel,getByPlaceholder,getByTextpour le texte statique.getByTestIdlorsque le balisage n'est pas sémantique. Demandez aux développeurs d'ajouterdata-testidplutôt que d'utiliser des chemins CSS.
N'utilisez jamais XPath par index, des noms de classe générés automatiquement, ou nth() sans une raison dans un commentaire.
Attentes
- N'utilisez pas
waitForTimeoutousleep. Attendez un état :await expect(locator).toBeVisible(),page.waitForResponse(url), ou une interrogation de l'API (expect.poll). - Les assertions dans Playwright réessayent. Utilisez
expect(locator)plutôt que de lire le texte et de comparer. - Si quelque chose est lent par conception (email, file d'attente), interrogez avec un délai d'attente et un message clair.
Données et état des tests
- Créez ce dont le test a besoin via l'API dans une fixture, et nettoyez après.
- Données uniques par exécution : suffixez avec un timestamp ou
test.info().workerIndex. - Connectez-vous une fois par rôle avec
storageState, pas via l'interface utilisateur dans chaque test. - Ne dépendez jamais de l'ordre entre les tests. Chaque test doit passer seul avec
--grep.
Structure
tests/
api/ vérifications rapides des règles et des permissions
e2e/ flux utilisateur, peu nombreux et importants
fixtures/ authentification, constructeurs de données, client API
pages/ objets de page uniquement lorsqu'une page est utilisée par 3+ tests
Nommez les tests comme un comportement : viewer cannot delete a project, pas test_delete_3.
Un comportement par test. Plusieurs lignes expect sont acceptables quand elles décrivent ce comportement unique.
Exemples dans examples/ : un flux UI avec configuration API, un test de permission API, et une version pytest.
Tiers et effets de bord
Simulez les fournisseurs de paiement, email, analytique et cartes avec page.route ou un double de test, sauf si le test porte sur cette intégration. Marquez les tests d'intégration réelle avec une balise (@integration) pour que CI puisse les exécuter séparément.
Dé-flaker un test
- Reproduisez :
npx playwright test <file> --repeat-each=20 --workers=4. - Ouvrez la trace (
--trace on) d'une exécution échouée et trouvez la première étape qui diffère d'une exécution réussie. - Causes habituelles : une attente fixe, un sélecteur qui correspond à deux éléments, des données partagées entre les workers, une animation, une requête qui se termine après l'assertion.
- Corrigez la cause. Les tentatives dans CI sont un filet de sécurité, pas une correction. Ne marquez jamais un test comme ignoré sans un lien vers un ticket dans la raison de l'ignorance.
Définition de fini
- Le test passe seul et dans la suite complète, trois exécutions consécutives.
- Vous l'avez vu échouer : cassez l'assertion ou l'état de l'application une fois et vérifiez que le message d'échec a du sens.
- Pas de secrets dans le code. Les identifiants proviennent des variables d'environnement.
- Le nom du test, l'ID du cas (dans une annotation ou une balise) et le résultat attendu sont lisibles dans le rapport.
Rapportez avec : fichiers modifiés, comment les exécuter, ce que les tests couvrent, et tout ce que vous n'avez pas pu automatiser et pourquoi.