Vos tests Playwright passent : le bouton de connexion répond, le tableau de bord s’affiche, le graphique se rend. Puis un client signale que les chiffres du graphique sont faux. Après analyse, l’API renvoyait bien 200, mais avec une charge utile mal formée. Votre suite end-to-end ne l’a pas détecté, car elle validait surtout l’interface affichée. C’est précisément la limite des tests navigateur seuls : ils doivent être complétés par des assertions d’API. Des outils comme Apidog permettent de valider les contrats d’API, les schémas et la sémantique des réponses avec le même niveau d’exigence que vos flux UI, puis d’exécuter ces validations en CI.
TL;DR
Combinez la fixture request de Playwright, page.route pour les interceptions réseau, et des scénarios Apidog basés sur la même spécification OpenAPI.
Objectif :
- une seule source de vérité :
openapi.yaml; - des fixtures partagées entre tests UI et API ;
- des assertions de schéma et de logique métier ;
- une exécution CI unique qui bloque les régressions UI ou API.
Introduction
Playwright est devenu un standard pour l’automatisation navigateur. Sa documentation sur les tests API montre qu’il est simple d’ajouter des appels comme :
const response = await request.get('/api/orders');
expect(response.status()).toBe(200);
Mais à grande échelle, cela ne suffit pas.
Les problèmes apparaissent vite :
- des centaines de tests vérifient uniquement les codes HTTP ;
- les corps de réponse ne sont pas validés ;
- les fixtures UI et API divergent ;
- les API ne peuvent pas toujours être simulées proprement quand le backend est lent ou indisponible.
La solution consiste à traiter votre spécification OpenAPI comme le contrat central. Playwright l’utilise indirectement via des fixtures et des données partagées. Apidog l’importe directement pour générer et valider des scénarios API complets.
Si vous voulez préparer l’environnement avant de suivre les étapes, vous pouvez télécharger Apidog, importer votre spécification OpenAPI, puis revenir à la configuration ci-dessous.
Dans cet article, vous allez mettre en place :
- une séparation claire entre tests UI et tests API ;
- une fixture Playwright réutilisable ;
- des données partagées avec Apidog ;
- une stratégie de simulation avec
page.route; - une exécution CI Playwright + Apidog ;
- des pratiques pour éviter la dérive de contrat.
Pour un aperçu plus large des outils de test API, consultez aussi cette comparaison des outils de test d’API pour les ingénieurs QA.
L’écart entre les tests Playwright et les assertions d’API
Un test Playwright classique vérifie qu’un utilisateur peut se connecter, naviguer et voir une page. C’est utile, mais cela ne garantit pas que l’API sous-jacente respecte son contrat.
Trois types de bugs passent souvent inaperçus.
1. Régression de forme de charge utile
L’API renvoie :
{
"totalCount": 42
}
alors que le frontend attendait :
{
"total_count": 42
}
Le statut est 200. L’UI peut afficher 0, une valeur par défaut ou une donnée partiellement correcte. Un test visuel peut passer alors que le contrat est cassé.
2. Dérive de logique métier
Un endpoint applique une remise de 10 % au lieu des 15 % attendus. Le frontend affiche simplement ce que l’API retourne. Si le test Playwright ne vérifie pas explicitement le calcul, il ne détecte rien.
3. Faible couverture des erreurs
Les tests end-to-end couvrent principalement le chemin nominal. Les cas suivants sont souvent ignorés :
- token expiré ;
- limite de débit ;
- conflit d’idempotence ;
- échec partiel ;
- erreur de validation ;
- webhook invalide.
Vous pouvez ajouter des appels request.get ou request.post dans Playwright. C’est utile pour quelques endpoints critiques. Mais cela devient difficile à maintenir avec des workflows API complets comme :
créer une commande → récupérer la commande → annuler la commande → vérifier le remboursement → valider le webhook.
La bonne répartition est donc :
- Playwright : flux UI, smoke tests API proches des actions utilisateur, interception réseau.
- Apidog : validation de schéma, scénarios API chaînés, chemins d’erreur, conformité contractuelle.
Les deux doivent consommer la même spécification OpenAPI. Pour approfondir cette approche, l’article sur les workflows API contract-first explique pourquoi la spécification doit piloter le développement.
Partager les fixtures entre Playwright et Apidog
Commencez par une structure simple :
.
├── openapi.yaml
├── fixtures/
│ └── order.json
├── tests/
│ ├── fixtures/
│ │ └── api.ts
│ └── orders.spec.ts
└── apidog/
└── scenarios/
└── checkout.json
La règle : openapi.yaml est le contrat, fixtures/ contient les données partagées.
Créer une fixture Playwright API
// tests/fixtures/api.ts
import { test as base, APIRequestContext, expect } from '@playwright/test';
import { readFileSync } from 'fs';
import path from 'path';
type ApiFixtures = {
apiRequest: APIRequestContext;
authToken: string;
sampleOrder: Record<string, unknown>;
};
export const test = base.extend<ApiFixtures>({
apiRequest: async ({ playwright }, use) => {
const ctx = await playwright.request.newContext({
baseURL: process.env.API_BASE_URL ?? 'https://api.staging.example.com',
extraHTTPHeaders: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
await use(ctx);
await ctx.dispose();
},
authToken: async ({ apiRequest }, use) => {
const res = await apiRequest.post('/auth/token', {
data: {
email: 'qa@example.com',
password: process.env.QA_PASSWORD,
},
});
expect(res.status()).toBe(200);
const body = await res.json();
await use(body.access_token);
},
sampleOrder: async ({}, use) => {
const raw = readFileSync(
path.join(__dirname, '..', '..', 'fixtures', 'order.json'),
'utf8',
);
await use(JSON.parse(raw));
},
});
export { expect };
Ensuite, importez test depuis cette fixture au lieu de @playwright/test.
Exemple de test API dans Playwright
// tests/orders.spec.ts
import { test, expect } from './fixtures/api';
test('POST /orders returns a valid order with 15 percent discount', async ({
apiRequest,
authToken,
sampleOrder,
}) => {
const res = await apiRequest.post('/orders', {
headers: {
Authorization: `Bearer ${authToken}`,
},
data: {
...sampleOrder,
coupon: 'SAVE15',
},
});
expect(res.status()).toBe(201);
const body = await res.json();
expect(body).toMatchObject({
id: expect.any(String),
status: 'pending',
discount_pct: 15,
total_cents: expect.any(Number),
});
expect(body.total_cents).toBeLessThan(sampleOrder.subtotal_cents);
});
Ce test vérifie une règle métier précise : la remise appliquée doit être de 15 %.
Mais il ne valide pas forcément tous les champs du modèle Order. C’est là qu’Apidog complète Playwright.
Importer la même spécification dans Apidog
Dans Apidog :
- créez ou ouvrez le projet ;
- cliquez sur Importer ;
- sélectionnez le même fichier
openapi.yaml; - générez les endpoints et schémas ;
- créez un scénario
POST /orders; - réutilisez la même charge utile que
fixtures/order.json; - activez la validation de schéma JSON contre le composant
Order.
Ainsi :
- Playwright vérifie le comportement métier critique ;
- Apidog vérifie la conformité complète du schéma ;
- les deux utilisent les mêmes données.
Si vous débutez avec les tests pilotés par spécification, ce guide sur les workflows API design-first détaille le modèle.
Pour les équipes qui viennent de Postman, les alternatives auto-hébergées à Postman expliquent aussi les options de migration.
Mettre en place le workflow Apidog + Playwright
Voici une configuration reproductible.
Étape 1 : centraliser la spécification OpenAPI
Placez openapi.yaml à la racine du dépôt.
Traitez-le comme du code :
- revue obligatoire en pull request ;
- versionnement des breaking changes ;
- validation automatique en CI ;
- exemples de réponses maintenus.
Si vous n’avez pas encore de spécification, générez une base depuis votre framework backend. FastAPI, NestJS et d’autres outils peuvent produire OpenAPI nativement. Apidog peut aussi aider à reconstruire une spécification depuis du trafic importé, par exemple via un fichier HAR.
Étape 2 : connecter Playwright
Installez Playwright :
npm init playwright@latest
Ajoutez vos scripts :
{
"scripts": {
"test:e2e": "playwright test"
}
}
Configurez l’environnement cible dans playwright.config.ts :
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
retries: 2,
use: {
baseURL: process.env.WEB_BASE_URL ?? 'https://staging.example.com',
trace: 'on-first-retry',
},
});
Gardez les tests courts : un scénario utilisateur ou API par test.
Étape 3 : créer les scénarios Apidog
Dans Apidog :
- importez
openapi.yaml; - créez un scénario par parcours critique ;
- chaînez les appels API ;
- stockez les valeurs dynamiques dans des variables ;
- ajoutez les assertions post-réponse ;
- exportez le scénario pour exécution CLI.
Exemples de scénarios utiles :
- inscription utilisateur ;
- connexion ;
- checkout ;
- remboursement ;
- livraison de webhook ;
- renouvellement de token ;
- erreur de validation ;
- conflit d’idempotence.
Exécution type :
apidog-cli run ./apidog/scenarios/checkout.json
Étape 4 : intercepter le réseau dans Playwright
Pour isoler l’UI d’un backend instable, utilisez page.route.
test('dashboard renders cached order list when offline', async ({
page,
sampleOrder,
}) => {
await page.route('**/api/orders', async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
orders: [sampleOrder],
}),
});
});
await page.goto('/dashboard');
await expect(page.getByTestId('order-row')).toHaveCount(1);
});
Ici, Playwright ne teste pas le backend. Il teste la réaction de l’interface à une réponse contrôlée.
En parallèle, Apidog teste le vrai endpoint GET /orders contre le backend réel ou contre un serveur de simulation.
Étape 5 : exécuter les deux suites en CI
Exemple avec GitHub Actions :
name: tests
on: [push, pull_request]
jobs:
playwright:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
apidog:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm i -g apidog-cli
- run: apidog-cli run ./apidog/scenarios/checkout.json --reporters cli,junit
L’échec de l’une des deux suites bloque la fusion.
La documentation GitHub Actions couvre aussi la mise en cache, les matrices et les workflows planifiés.
Pour les équipes sans QA dédiée, cette comparaison des outils de test d’API pour les ingénieurs QA aide à définir la propriété de chaque suite.
Étape 6 : détecter la dérive de contrat
Ajoutez une tâche planifiée qui compare :
- la version de
openapi.yamltestée ; - la version exposée par le backend réel.
Si un champ change de type, si un champ requis disparaît ou si une énumération change, la CI doit échouer avant même que le bug n’arrive en production.
C’est le type de contrôle qui évite le classique :
200 OK, mais charge utile incorrecte.
Techniques avancées et astuces pratiques
Activer les traces Playwright
Dans playwright.config.ts :
use: {
trace: 'on-first-retry',
}
Lorsqu’un test échoue en CI, vous récupérez :
- appels réseau ;
- snapshots DOM ;
- logs console ;
- actions utilisateur ;
- captures temporelles.
Combinez cela avec un rapport Apidog côté API pour identifier rapidement si l’échec vient de l’interface ou du contrat backend.
Utiliser les serveurs de simulation Apidog
Les serveurs de simulation sont utiles quand :
- le backend de staging est instable ;
- la base de données est réinitialisée ;
- une API dépendante est indisponible ;
- le frontend doit avancer avant que le backend soit terminé.
Le principe :
- Apidog génère une simulation depuis OpenAPI ;
- Playwright pointe vers cette simulation ;
- les scénarios Apidog peuvent continuer à valider le backend réel séparément.
Pour un exemple plus large autour des simulations et de la génération de tests, consultez l’article sur la génération de tests API assistée par l’IA.
Limiter les retries
Dans Playwright :
retries: 2
Si un test nécessite cinq tentatives pour réussir, il est instable. Le masquer avec plus de retries ne corrige pas le problème.
Même logique côté scénarios API : limitez les retries par requête et analysez les causes réelles.
Faire échouer la CI en cas de dérive de schéma
Une non-conformité de schéma ne doit pas être un simple warning.
Bonne pratique :
- échec par défaut ;
- exception temporaire uniquement via variable explicite ;
- justification obligatoire dans la pull request.
Exemple :
ALLOW_SCHEMA_DRIFT=true apidog-cli run ./apidog/scenarios/checkout.json
À utiliser uniquement comme dérogation temporaire.
Étiqueter les tests par priorité
Vous pouvez organiser les tests en catégories :
-
@smoke: à chaque push ; -
@regression: sur les PR versmain; -
@nightly: suite complète ; - scénarios API complets : nightly ou avant release.
Exemple Playwright :
test.describe('checkout @smoke', () => {
test('user can complete checkout', async ({ page }) => {
// ...
});
});
Pour les flux avec état :
test.describe.configure({ mode: 'serial' });
Erreurs courantes à éviter
- Vérifier uniquement
status === 200. - Coder en dur les tokens bearer.
- Maintenir deux fichiers de fixtures différents.
- Oublier d’exécuter l’Apidog CLI en CI.
- Utiliser
page.routecomme substitut aux tests API réels. - Ne pas versionner
openapi.yaml. - Laisser les changements de contrat passer sans revue.
Pour les cas non déterministes, notamment avec des agents IA, ce guide sur comment tester les API des agents IA couvre des patterns supplémentaires.
Alternatives et comparaison d’outils
Plusieurs piles peuvent valider les API à côté des tests navigateur.
| Pile | Forces | Faiblesses | Idéal pour |
|---|---|---|---|
Playwright seul avec fixture request
|
Un seul outil, rapide, intégré à la suite | Validation de schéma limitée, peu adapté aux scénarios API chaînés | Petites équipes, API simples |
| Playwright + Postman | Écosystème mature, Newman CLI | Collections pouvant dériver d’OpenAPI, collaboration payante selon les besoins | Équipes déjà fortement investies dans Postman |
| Playwright + Apidog | Source OpenAPI unique, validation de schéma, simulations, CLI, workflow design-first | Deux outils à apprendre, discipline nécessaire sur les spécifications | Équipes qui veulent des tests pilotés par spécification |
| Cypress + plugin cy-api | Familier pour les utilisateurs Cypress | Tests API contraints par l’écosystème Cypress, plugins variables | Bases de code Cypress existantes |
| Pact | Contrats forts entre consommateurs et fournisseurs | Courbe d’apprentissage, broker, pas orienté UI | Organisations microservices avec nombreux consommateurs internes |
Si vous migrez depuis des outils plus anciens, ces articles sur les alternatives aux scripts Groovy de SoapUI et les alternatives à ReadyAPI peuvent aider. Pour un workflow local, les extensions VSCode de client REST sont aussi utiles.
Cas d’utilisation réels
Paiement e-commerce
Une équipe retail utilise Playwright pour tester le parcours panier → paiement → confirmation.
En parallèle, Apidog vérifie :
- l’intention de paiement ;
- la fraude ;
- la décrémentation du stock ;
- les erreurs de paiement ;
- les webhooks.
Quand une passerelle modifie error_code en errorCode, Apidog détecte la dérive de schéma rapidement. Playwright aurait seulement affiché un échec de paiement générique.
Tableau de bord SaaS
Une équipe B2B utilise Playwright pour vérifier le rendu du dashboard et Apidog pour valider les endpoints d’agrégation.
Apidog peut affirmer que l’API renvoie correctement :
- sommes ;
- percentiles ;
- séries temporelles ;
- regroupements ;
- filtres.
Un graphique peut sembler correct visuellement tout en reposant sur une agrégation fausse. Les assertions API couvrent ce risque.
Workflow basé sur les webhooks
Une équipe fintech utilise Playwright pour le portail utilisateur et Apidog pour les scénarios webhook.
Les scénarios API vérifient :
- signature valide ;
- rejet des doublons ;
- idempotence ;
- retries ;
- cohérence éventuelle ;
- erreurs 4xx attendues.
Conclusion
Playwright est excellent pour tester les flux navigateur. Pour les tests API profonds, il doit être complété par une couche dédiée.
Le duo Playwright + Apidog vous donne :
- une spécification OpenAPI comme contrat ;
- des fixtures partagées ;
- une validation de schéma ;
- des scénarios API chaînés ;
- des simulations pour le développement hors ligne ;
- une CI unique pour les régressions UI et API ;
- une séparation claire des responsabilités.
Commencez petit :
- choisissez un parcours critique, comme l’inscription ou le paiement ;
- créez la fixture Playwright ;
- importez
openapi.yamldans Apidog ; - construisez le scénario API correspondant ;
- exécutez les deux suites en CI ;
- élargissez progressivement la couverture.
FAQ
Puis-je valider les API dans Playwright sans Apidog ?
Oui. Utilisez la fixture request de Playwright avec des assertions manuelles.
Exemple :
const res = await request.get('/orders');
expect(res.status()).toBe(200);
const body = await res.json();
expect(body.orders).toBeInstanceOf(Array);
C’est suffisant pour des smoke tests. Pour la validation de schéma, les scénarios chaînés, les simulations et les chemins d’erreur à grande échelle, un outil dédié comme Apidog est plus adapté. Consultez aussi cette comparaison des outils de test d’API pour les ingénieurs QA.
Ai-je besoin d’une spécification OpenAPI ?
Oui, pour tirer pleinement parti de cette approche.
Sans OpenAPI, vous pouvez exécuter Playwright et Apidog côte à côte, mais vous perdez :
- la source de vérité partagée ;
- la validation automatique de schéma ;
- la génération cohérente d’exemples ;
- la détection fiable de dérive.
Comment gérer l’authentification entre Playwright et Apidog ?
Récupérez un token frais au début de chaque exécution.
Dans Playwright, utilisez une fixture ou un beforeAll.
Dans Apidog, stockez le token dans une variable d’environnement ou une variable de scénario.
Évitez les tokens statiques dans le dépôt.
Apidog peut-il remplacer Playwright ?
Non.
Apidog teste les workflows API. Il ne rend pas le navigateur et ne valide pas :
- les clics ;
- le texte visible ;
- la navigation ;
- la mise en page ;
- les interactions utilisateur.
Playwright et Apidog couvrent des surfaces différentes.
Que faire si le backend de staging est instable ?
Utilisez un serveur de simulation Apidog basé sur openapi.yaml.
Votre frontend peut continuer à être testé avec Playwright contre des réponses stables, pendant qu’Apidog valide le backend réel lorsqu’il est disponible.
Comment garder une CI rapide ?
Séparez les suites :
- smoke tests à chaque push ;
- régression sur les PR vers
main; - scénarios API complets la nuit ;
- parallélisation Playwright avec
workers; - parallélisation Apidog via la CLI si disponible.
Ai-je besoin d’un plan Apidog payant pour la CI ?
L’Apidog CLI peut être utilisée en local et en CI pour exécuter des scénarios. Vérifiez la page de tarification actuelle avant un déploiement à grande échelle, surtout si vous avez des besoins avancés de collaboration ou de gouvernance.
Top comments (0)