Playwright Python : tutoriel complet en français (avec pytest)
Playwright pour Python s'installe en deux commandes, pip install pytest-playwright puis playwright install, et se pilote avec pytest grâce à la fixture page. Ce tutoriel va du premier script à l'exécution dans GitHub Actions : locators, assertions qui réessaient, Codegen, Trace Viewer, tests d'API et Page Object. Tout le code a été exécuté avec Playwright 1.63 et pytest-playwright 0.9 avant publication.
- Installation :
pip install pytest-playwright, puisplaywright installpour télécharger Chromium, Firefox et WebKit - Tests : une fonction
test_...qui reçoit la fixturepage, et des assertionsexpect(...)qui réessaient jusqu'au délai d'attente - Locators : privilégier
get_by_role,get_by_label,get_by_textetget_by_test_idplutôt que les sélecteurs CSS - Débogage :
--headedpour voir le navigateur,--tracing onpuisplaywright show-tracepour rejouer un test pas à pas - Python ou TypeScript : TypeScript offre le runner le plus complet ; Python convient aux équipes qui travaillent déjà en Python
Qu'est-ce que Playwright pour Python ?
Playwright est une bibliothèque open source de Microsoft qui automatise Chromium, Firefox et WebKit avec une seule API. La version Python est officielle, maintenue par Microsoft comme la version TypeScript, et reçoit les mêmes fonctionnalités de navigateur. Elle propose deux styles : une API synchrone (la plus simple pour les tests) et une API asynchrone basée sur asyncio.
Ce qui distingue Playwright des outils plus anciens : il attend automatiquement qu'un élément soit visible, stable et cliquable avant d'agir, ce qui supprime la plupart des sleep et des tests instables. Pour une présentation générale de l'outil, voir notre guide Playwright en français ; ici, on se concentre sur Python.
Étape 1 : installer Playwright Python
Travaillez dans un environnement virtuel pour isoler les dépendances du projet :
python -m venv .venv
source .venv/bin/activate # Windows : .venv\Scripts\activate
pip install pytest-playwright
playwright install
pytest-playwright installe à la fois la bibliothèque playwright et le plugin pytest. La commande playwright install télécharge les navigateurs ; pour n'en prendre qu'un, précisez-le : playwright install chromium. Sur une machine Linux neuve (ou en CI), ajoutez --with-deps pour installer aussi les bibliothèques système dont les navigateurs ont besoin.
Étape 2 : un premier script avec l'API synchrone
Avant d'écrire des tests, un script de quelques lignes suffit pour vérifier que tout fonctionne. Il ouvre la documentation Playwright, affiche le titre de la page et enregistre une capture d'écran :
premier_script.pyfrom playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch() # headless par défaut
page = browser.new_page()
page.goto("https://playwright.dev/python/")
print(page.title())
page.screenshot(path="accueil.png")
browser.close()
Lancez python premier_script.py : le titre s'affiche dans le terminal et accueil.png apparaît dans le dossier. Le navigateur tourne sans fenêtre (mode headless) ; passez p.chromium.launch(headless=False) pour le voir. Pour une application asynchrone, l'équivalent s'importe depuis playwright.async_api.
Étape 3 : votre premier test avec pytest
Pour des tests, laissez pytest-playwright gérer le navigateur. Le plugin fournit la fixture page : un onglet neuf, dans un contexte isolé, pour chaque test. Créez un dossier tests/ et un fichier dont le nom commence par test_ :
import re
from playwright.sync_api import Page, expect
def test_titre_de_la_page(page: Page):
page.goto("https://playwright.dev/python/")
expect(page).to_have_title(re.compile("Playwright"))
def test_lien_get_started(page: Page):
page.goto("https://playwright.dev/python/")
page.get_by_role("link", name="Get started").click()
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
Lancez pytest à la racine du projet : les deux tests s'exécutent dans Chromium, sans fenêtre, et pytest affiche 2 passed. Aucun browser.close() à écrire : la fixture ferme tout à la fin de chaque test.
Étape 4 : choisir les bons locators
Un locator décrit comment retrouver un élément. Playwright recommande de cibler ce que l'utilisateur voit (rôle, libellé, texte) plutôt que la structure HTML, qui change souvent. Un test écrit ainsi survit aux refontes graphiques.
| Locator | Cible | Exemple |
|---|---|---|
get_by_role | Rôle d'accessibilité et nom | get_by_role("button", name="Envoyer") |
get_by_label | Champ de formulaire par son libellé | get_by_label("Adresse e-mail") |
get_by_text | Texte visible | get_by_text("Merci") |
get_by_placeholder | Texte indicatif d'un champ | get_by_placeholder("Rechercher") |
get_by_test_id | Attribut data-testid | get_by_test_id("envoyer") |
locator | Sélecteur CSS ou XPath (dernier recours) | locator("#panier .total") |
Exemple complet sur un petit formulaire injecté avec page.set_content, pratique pour s'exercer sans serveur :
from playwright.sync_api import Page, expect
FORMULAIRE = """
<form>
<label for="email">Adresse e-mail</label>
<input id="email" type="email">
<button type="button" data-testid="envoyer">Envoyer</button>
</form>
<p id="message"></p>
<script>
document.querySelector('[data-testid="envoyer"]').addEventListener('click', () => {
document.getElementById('message').textContent = 'Merci, inscription confirmée';
});
</script>
"""
def test_inscription(page: Page):
page.set_content(FORMULAIRE)
page.get_by_label("Adresse e-mail").fill("lea@example.com")
page.get_by_test_id("envoyer").click()
expect(page.get_by_text("Merci, inscription confirmée")).to_be_visible()
expect(page.get_by_label("Adresse e-mail")).to_have_value("lea@example.com")
L'attribut lu par get_by_test_id est data-testid par défaut. Si votre application utilise un autre nom, configurez-le une fois, par exemple dans une fixture :
playwright.selectors.set_test_id_attribute("data-qa")
Étape 5 : des assertions qui attendent (web-first)
Les assertions expect de Playwright réessaient jusqu'à ce que la condition soit vraie ou que le délai expire (5 secondes par défaut). C'est la différence majeure avec un assert Python classique, qui vérifie une seule fois et échoue si la page n'a pas encore fini de se mettre à jour.
expect(page).to_have_title(...)etexpect(page).to_have_url(...)pour la page ;expect(locator).to_be_visible(),to_be_enabled(),to_be_checked()pour l'état d'un élément ;expect(locator).to_have_text(...),to_contain_text(...),to_have_value(...),to_have_count(...)pour le contenu ;expect(locator).not_to_be_visible()pour la négation.
Réservez assert aux valeurs déjà calculées, comme le contenu JSON d'une réponse d'API.
Étape 6 : les options de ligne de commande utiles
pytest-playwright ajoute des options à pytest. Les plus utiles au quotidien :
| Option | Effet |
|---|---|
--headed | Affiche le navigateur pendant les tests |
--browser firefox | Choisit le navigateur (chromium, firefox, webkit) ; répétable pour en lancer plusieurs |
--slowmo 500 | Ralentit chaque action de 500 ms, pour suivre à l'écran |
--base-url URL | Permet d'écrire page.goto("/chemin") |
--tracing on | Enregistre une trace par test (retain-on-failure pour ne garder que les échecs) |
--screenshot only-on-failure | Capture d'écran des tests en échec |
--video retain-on-failure | Vidéo des tests en échec |
--output DOSSIER | Dossier des traces, captures et vidéos (test-results par défaut) |
Pour ne pas les retaper, placez-les dans un fichier pytest.ini à la racine :
[pytest]
pythonpath = .
addopts = --base-url https://playwright.dev --tracing retain-on-failure
Étape 7 : générer du code avec Codegen
Codegen ouvre un navigateur, enregistre vos clics et vos saisies, et écrit le code Playwright correspondant en direct :
playwright codegen --target python-pytest https://playwright.dev
L'option --target python-pytest produit directement une fonction de test pytest ; -o test_genere.py enregistre le résultat dans un fichier. Codegen choisit en priorité des locators par rôle et par texte. Considérez le code généré comme un brouillon : renommez, ajoutez les assertions qui comptent pour le métier et supprimez les étapes inutiles.
Étape 8 : comprendre un échec avec le Trace Viewer
Une trace contient, pour chaque action, une capture du DOM avant et après, la console, les requêtes réseau et le code source. Lancez les tests avec --tracing on (ou retain-on-failure), puis ouvrez la trace produite :
pytest --tracing on
playwright show-trace test-results/tests-test-accueil-py-test-lien-get-started-chromium/trace.zip
Chaque test a son propre sous-dossier dans test-results/. Le Trace Viewer permet de remonter le temps action par action : c'est l'outil le plus efficace pour comprendre un test qui échoue seulement en CI. Pour déboguer en direct, PWDEBUG=1 pytest -s ouvre l'inspecteur Playwright et met le test en pause à chaque étape.
Étape 9 : tester une API avec Playwright Python
Playwright envoie aussi des requêtes HTTP sans navigateur, via APIRequestContext. On crée le contexte une fois par session dans une fixture, puis on l'utilise dans les tests :
from typing import Generator
import pytest
from playwright.sync_api import Playwright, APIRequestContext, expect
@pytest.fixture(scope="session")
def api(playwright: Playwright) -> Generator[APIRequestContext, None, None]:
contexte = playwright.request.new_context(base_url="https://api.github.com")
yield contexte
contexte.dispose()
def test_depot_playwright_python(api: APIRequestContext):
reponse = api.get("/repos/microsoft/playwright-python")
expect(reponse).to_be_ok()
assert reponse.json()["name"] == "playwright-python"
expect(reponse).to_be_ok() vérifie un statut entre 200 et 299. Dans un test d'interface, page.request donne accès au même client en partageant les cookies du navigateur : pratique pour créer des données par l'API avant de tester l'écran. Pour comparer les outils de test d'API, lisez notre article Tests API : définition, outils et exemples.
Étape 10 : organiser le projet (conftest.py et Page Object)
Au-delà de quelques tests, regroupez les locators et les actions de chaque page dans une classe : c'est le Page Object Model. Les tests deviennent lisibles et un changement d'interface ne se corrige qu'à un seul endroit. Une structure simple :
mon-projet/
├── pages/
│ ├── __init__.py
│ └── accueil.py
├── tests/
│ ├── conftest.py
│ ├── test_accueil.py
│ └── test_parcours.py
├── pytest.ini
└── requirements.txt
pages/accueil.py
from playwright.sync_api import Page
class AccueilPage:
def __init__(self, page: Page):
self.page = page
self.lien_get_started = page.get_by_role("link", name="Get started")
def ouvrir(self):
self.page.goto("/python/")
def aller_a_l_installation(self):
self.lien_get_started.click()
Le fichier conftest.py est chargé automatiquement par pytest : on y déclare les fixtures partagées, ici une fixture qui construit la page d'accueil à partir de la fixture page du plugin.
import pytest
from playwright.sync_api import Page
from pages.accueil import AccueilPage
@pytest.fixture
def accueil(page: Page) -> AccueilPage:
return AccueilPage(page)
tests/test_parcours.py
from playwright.sync_api import expect
from pages.accueil import AccueilPage
def test_parcours_installation(accueil: AccueilPage):
accueil.ouvrir()
accueil.aller_a_l_installation()
expect(accueil.page.get_by_role("heading", name="Installation")).to_be_visible()
La ligne pythonpath = . du pytest.ini rend le paquet pages importable depuis les tests, et --base-url permet les chemins relatifs dans goto. Pour aller plus loin sur les patrons de conception, voir Page Object Model et design patterns de test, et pour faire varier les données d'un même test, le data-driven testing avec Python.
Étape 11 : lancer les tests dans GitHub Actions
Un fichier de workflow suffit pour exécuter les tests à chaque push et conserver les traces des échecs :
.github/workflows/playwright.ymlname: Tests Playwright
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
tests:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Installer les dépendances
run: pip install -r requirements.txt
- name: Installer les navigateurs
run: python -m playwright install --with-deps
- name: Lancer les tests
run: pytest --tracing retain-on-failure
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: traces-playwright
path: test-results/
Le fichier requirements.txt contient au minimum pytest-playwright ; épinglez la version pour que la CI et les postes de l'équipe utilisent les mêmes navigateurs. En cas d'échec, téléchargez l'artefact traces-playwright et ouvrez la trace avec playwright show-trace. Les principes généraux de l'intégration continue sont détaillés dans Tests automatisés en CI/CD.
Playwright en Python ou en TypeScript ?
Les deux versions pilotent les mêmes navigateurs avec les mêmes concepts. La différence tient surtout à l'outillage autour :
| Critère | Python (pytest-playwright) | TypeScript (@playwright/test) |
|---|---|---|
| Lanceur de tests | pytest et son écosystème de plugins | Lanceur intégré à Playwright |
| Exécution en parallèle | Via le plugin pytest-xdist | Incluse (workers) |
| Rapport HTML | Via un plugin pytest | Inclus |
| Mode UI, agents de test | Non | Oui |
| Profil d'équipe typique | Équipes Python, data, back-end Django ou FastAPI | Équipes front-end et full-stack JavaScript |
En pratique : si votre équipe et votre application sont déjà en Python, restez en Python, vous partagerez les outils et les fixtures. Si vous partez de zéro ou visez des postes de QA automaticien, TypeScript donne accès à l'outillage le plus complet (lanceur, rapport, mode UI). Nos formations Playwright utilisent TypeScript ; tout ce que vous apprenez ici (locators, assertions web-first, traces, Page Object) s'y transpose sans effort. Pour comparer avec l'outil historique, lisez Playwright vs Selenium.
Questions fréquentes
Playwright fonctionne-t-il avec Python ?
Oui. Microsoft maintient une bibliothèque Playwright officielle pour Python, avec une API synchrone et une API asynchrone, et un plugin pytest (pytest-playwright) qui fournit les fixtures page, context et browser.
Faut-il pytest pour utiliser Playwright en Python ?
Non, un simple script suffit pour automatiser un navigateur. Pour écrire des tests, le plugin officiel pytest-playwright est recommandé : il gère le lancement des navigateurs, l'isolation de chaque test et les options comme --headed, --browser ou --tracing.
Playwright Python est-il gratuit ?
Oui. Playwright est un projet open source publié par Microsoft sous licence Apache 2.0, gratuit pour un usage personnel comme commercial.
Playwright Python ou Selenium : lequel choisir ?
Pour un nouveau projet, Playwright apporte l'attente automatique, des assertions qui réessaient, le Trace Viewer et les tests d'API dans le même outil. Selenium reste pertinent quand une équipe a déjà une grosse base de tests Selenium ou dépend de Selenium Grid.
Comment lancer les tests Playwright Python en parallèle ?
pytest-playwright ne parallélise pas seul : installez le plugin pytest-xdist puis lancez pytest --numprocesses auto. Chaque processus démarre son propre navigateur.
Passer de ce tutoriel à un vrai projet
Notre formation Playwright certifiante (40 h) reprend ces notions en TypeScript sur un projet complet : locators, Page Object, tests d'API, GitHub Actions et rapport de tests. Pour commencer sans engagement, le cours Playwright gratuit propose 7 leçons de 7 minutes.
Voir la formation Playwright Suivre le cours gratuitéquipe ADC — Experts QA & IA
AutomationDataCamp — Certifiés ISTQB
Formateurs en automatisation des tests avec Playwright, en TypeScript comme en Python, et en intégration des tests dans la CI. Découvrir l'équipe →
Playwright, tests API, CI et IA appliquée au test, sans prérequis. Examens ISTQB CTFL et CT-GenAI inclus. 1 500 € en 1 à 4 fois ou financement entreprise.
Voir le programme de la formation testeur QA automatisation & IALe module 1 de notre formation certifiante, en 7 leçons courtes, sans engagement.
Commencer le cours gratuitArticles similaires

Tests API : définition, outils et exemples
Postman, REST Assured, Playwright : quel outil pour quel besoin.
Lire la suite : Tests API, définition, outils et exemples
Tests automatisés en CI/CD
GitHub Actions, GitLab CI, Jenkins : exemples pratiques.
Lire la suite : Tests automatisés en CI/CD