Tester une API, c'est vérifier directement l'interface entre votre frontend et votre backend. On envoie des requêtes HTTP, on contrôle les codes de statut, on valide les corps de réponse. On teste aussi l'authentification, la gestion des erreurs et les cas limites que l'interface utilisateur n'expose jamais.
Ce qu'est une API du point de vue du test
Une API est un contrat. Un système dit : "Envoyez-moi une requête dans cette forme, et je vous donnerai une réponse dans cette autre forme." Votre rôle en tant qu'ingénieur QA est de vérifier que ce contrat tient. Le système doit livrer ce qu'il promet, rejeter ce qu'il doit rejeter, et échouer proprement quand quelque chose se passe mal.
En pratique, la plupart des APIs que vous testerez sont des APIs REST qui communiquent via HTTP. Une application de réservation de voyages a un endpoint API qui crée une réservation. Un système de gestion d'utilisateurs a un endpoint qui renvoie une liste d'utilisateurs. Une plateforme e-commerce a des endpoints pour ajouter au panier, vérifier les stocks et traiter les paiements.
Quand vous testez via l'interface utilisateur, vous testez l'API indirectement, car l'UI appelle l'API à votre place. Quand vous testez l'API directement, vous supprimez l'UI de l'équation. Résultat : des tests plus rapides, des messages d'échec plus clairs, et la capacité de tester des scénarios que l'UI n'expose pas. Que se passe-t-il si quelqu'un envoie un prix négatif, un champ obligatoire vide, ou une requête sans authentification ?
Les bases HTTP pour les testeurs
Toute interaction avec une API est une requête HTTP suivie d'une réponse HTTP. Voici ce que contient chaque côté.
Une requête a quatre parties : la méthode, l'URL, les headers, et un corps optionnel.
La méthode indique au serveur l'opération souhaitée. Les quatre que vous utiliserez constamment sont GET (récupérer des données), POST (créer quelque chose), PUT ou PATCH (mettre à jour quelque chose), et DELETE (supprimer quelque chose). Envoyer un GET à /api/users renvoie une liste d'utilisateurs. Envoyer un POST à /api/users avec des données dans le corps crée un nouvel utilisateur.
L'URL est l'adresse de la ressource. Elle a généralement une base comme https://api.example.com, un chemin comme /users/42, et parfois des paramètres de requête comme ?status=active&page=2.
Les headers transportent des métadonnées : le type de contenu du corps (Content-Type: application/json) et les identifiants d'authentification (Authorization: Bearer eyJ...). Ils indiquent aussi au serveur le format accepté par le client (Accept: application/json).
Le corps contient les données envoyées, généralement en JSON pour les APIs REST modernes.
Une réponse reflète cette structure. Elle a un code de statut, des headers, et un corps. Le code de statut est la partie la plus importante pour le test :
- 200 OK : la requête a réussi, voici ce que vous avez demandé
- 201 Created : quelque chose a été créé avec succès
- 400 Bad Request : votre requête est mal formée ou manque de champs obligatoires
- 401 Unauthorized : vous n'êtes pas authentifié
- 403 Forbidden : vous êtes authentifié mais vous n'avez pas le droit de faire ça
- 404 Not Found : cette ressource n'existe pas
- 422 Unprocessable Entity : la requête est bien formée mais sémantiquement invalide
- 500 Internal Server Error : le serveur a planté
Quoi tester dans une API
L'instinct est de tester uniquement le chemin nominal : envoyer des données valides, recevoir un 200, terminé. Cette approche détecte peut-être 20% des bugs. Voici un cadre plus complet.
Les chemins nominaux vérifient que l'API fait ce qu'elle est censée faire quand elle est utilisée correctement. Un POST pour créer un utilisateur avec des données valides doit renvoyer 201 et l'objet utilisateur créé. Un GET avec l'ID de cet utilisateur doit renvoyer 200 et les mêmes données. Les cas d'erreur sont là où les APIs sont le plus souvent cassées. Que se passe-t-il quand un champ obligatoire est absent ? Quand l'ID dans l'URL n'existe pas ? Quand l'utilisateur n'est pas authentifié ? Chacun de ces cas doit renvoyer un code de statut précis et un message d'erreur significatif. Vérifiez que c'est le cas. Les cas limites sondent les frontières de ce que l'API accepte. Que se passe-t-il avec une chaîne vide là où du texte est attendu ? Un zéro ou un nombre négatif pour une quantité ? Une chaîne exactement d'un caractère au-dessus de la longueur maximale ? Une date dans le passé pour un endpoint "événements futurs uniquement" ? Les bases de sécurité ont leur place dans toute suite de tests API, même au niveau débutant. Peut-on accéder aux données d'un autre utilisateur en devinant son ID ? L'API accepte-t-elle des requêtes sans authentification ? Renvoie-t-elle plus de données que le client devrait voir (sur-récupération) ? Ce ne sont pas des tests d'intrusion, juste des vérifications de bon sens.Un modèle mental utile : pour chaque endpoint, posez-vous trois questions. Qu'est-ce qui doit fonctionner ? Qu'est-ce qui doit échouer ? À quoi doit ressembler l'erreur quand ça échoue ?
Outils : Postman, Playwright et curl
Trois outils couvrent la plupart de ce dont vous avez besoin.
curl est le moyen le plus rapide de faire une requête HTTP ponctuelle depuis le terminal. Rien à installer ; il est déjà sur chaque machine de développeur. À utiliser pour les vérifications rapides pendant l'exploration :# Requête GET
curl https://lab.becomeqa.com/api/items
# POST avec un corps JSON
curl -X POST https://lab.becomeqa.com/api/items \
-H "Content-Type: application/json" \
-d '{"destination": "Tokyo", "status": "planned"}'
# Avec un header Authorization
curl https://lab.becomeqa.com/api/items \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."request fonctionne sans ouvrir de navigateur, s'exécute en millisecondes, et s'intègre avec vos rapports de test existants :
import { test, expect } from '@playwright/test';
test('POST /api/items crée un nouvel élément', async ({ request }) => {
const response = await request.post('https://lab.becomeqa.com/api/items', {
data: {
destination: 'Tokyo',
status: 'planned'
}
});
expect(response.status()).toBe(201);
const created = await response.json();
expect(created).toHaveProperty('id');
expect(created.destination).toBe('Tokyo');
});Le flux de travail est simple : explorez avec Postman et curl, automatisez avec Playwright.
Anatomie d'un test d'API REST
Un bon test d'API vérifie plus que le code de statut. Voici ce qu'il faut asserter sur chaque réponse.
Le code de statut est la première vérification. Assurez-le avant d'asserter quoi que ce soit d'autre. Si le statut est mauvais, tout le reste n'a pas d'importance.
La structure du corps de réponse compte. Si l'API promet de renvoyer un objet utilisateur avec id, email et role, votre test doit vérifier que ces trois champs sont présents dans chaque réponse. Ça détecte les régressions silencieuses où quelqu'un ajoute un champ obligatoire au contrat frontend mais oublie de l'inclure dans la réponse API.
Les valeurs des champs comptent, pas seulement leur présence. Si vous avez créé un utilisateur avec l'email test@example.com, la réponse doit refléter exactement cet email. Si l'API renvoie un champ statut, vérifiez que c'est l'une des valeurs attendues, pas juste une chaîne quelconque.
Les headers de réponse transportent aussi de l'information. Vérifiez Content-Type: application/json si vous attendez du JSON. Pour les endpoints qui renvoient des données paginées, vérifiez les headers de pagination comme X-Total-Count ou les liens dans le corps de réponse.
Le temps de réponse est un signal. Playwright ne fournit pas d'assertions sur le temps de réponse nativement, mais vous pouvez le mesurer manuellement. Un endpoint qui répond normalement en 50ms et qui prend 2000ms vaut la peine d'être signalé même si les données sont correctes.
L'authentification dans les tests API
Presque toute API en production exige une authentification. Les deux patterns que vous rencontrerez quotidiennement sont les clés API et les tokens Bearer.
Les clés API sont des chaînes statiques qui identifient une application cliente. Elles sont généralement envoyées dans un header :curl https://api.example.com/data \
-H "X-API-Key: your-api-key-here"Dans vos tests automatisés, ne codez jamais la clé en dur. Stockez-la dans une variable d'environnement et lisez-la depuis là. Ça garde les secrets hors de votre code de test et facilite le passage entre les identifiants de staging et de production.
Les tokens Bearer sont dynamiques. Ils expirent, et vous en obtenez généralement un en appelant d'abord un endpoint de connexion. Le pattern dans vos tests est toujours le même : appelez l'endpoint d'authentification, extrayez le token, passez-le dans le headerAuthorization des requêtes suivantes.
Tester les cas limites liés à l'authentification est l'une des formes les plus précieuses de tests API que vous puissiez faire. Pensez aux tokens invalides, aux tokens absents, et aux tokens avec de mauvaises permissions. Les conséquences d'une authentification mal gérée sont graves, et ces bugs vivent souvent dans l'API, pas dans l'UI où vos tests UI les détecteraient.
Où le test API s'inscrit dans la pyramide de tests
La pyramide de tests est un modèle de distribution des tests. La base contient de nombreux tests unitaires, rapides et peu coûteux, qui testent des fonctions individuelles. Le milieu rassemble les tests d'intégration et d'API, qui testent comment les systèmes se parlent. Et au sommet, peu de tests UI testent les parcours utilisateurs complets.
Les tests API se situent dans la zone optimale. Ils sont nettement plus rapides que les tests UI. Un test API typique s'exécute en 50 à 200 millisecondes contre 3 à 10 secondes pour un test UI. Ils sont plus stables parce qu'ils ne cassent pas quand un libellé de bouton change ou qu'un sélecteur CSS bouge. Et ils testent la couche où la plupart des bugs backend vivent réellement.
Un rapport pratique pour une application web classique : pour chaque test UI qui couvre un parcours utilisateur, écrivez 3 à 5 tests API qui couvrent les endpoints sous-jacents. Le test UI vérifie que les pièces s'assemblent correctement. Les tests API vérifient que chaque pièce fonctionne correctement de façon isolée.
C'est particulièrement important pour la logique métier. Si une application e-commerce calcule les remises côté backend, testez ce calcul via l'API, pas en remplissant un formulaire de paiement dans un navigateur. Le test API sera dix fois plus rapide et couvrira chaque cas limite (zéro article, codes promo expirés, remises cumulées) sans aucune fragilité UI.
Comment appliquer ça dès lundi matin
Pas besoin de refactoriser toute votre suite de tests. Voici comment démarrer petit cette semaine.
Choisissez une fonctionnalité qui a des tests UI mais pas de tests API. Regardez le trafic réseau dans Chrome DevTools pendant que vous utilisez cette fonctionnalité. Vous verrez les appels API que l'UI effectue. Prenez l'endpoint le plus important (généralement celui qui crée ou récupère les données principales) et écrivez un premier test API dans Postman.
Vérifiez le chemin nominal. Puis écrivez un test pour un 404 (demandez une ressource avec un ID inexistant). Puis un test pour un 400 (envoyez un POST avec un champ obligatoire manquant). Trois tests qui prennent 30 minutes à écrire, et vous avez établi le pattern.
Ensuite, déplacez ces trois tests dans Playwright pour qu'ils s'exécutent en CI avec vos tests existants. Utilisez la structure de code des exemples de cet article. Lancez-les une fois pour confirmer qu'ils passent.
À partir de là, élargissez la couverture en vous demandant : "Quel est le prochain endpoint le plus important ?" et "Quels cas d'erreur cet endpoint a-t-il que je ne teste pas ?"
En quelques semaines, vous aurez une couche de tests API qui détecte les bugs backend en secondes. Plus besoin de les laisser remonter via des tests UI qui tournent pendant des minutes.
→ See also: Tests d'API avec Playwright: Au-delà de l'Interface | Qu'est-ce qu'une API REST? Un Guide Pratique pour les Ingénieurs QA | Codes de Statut HTTP que Tout Ingénieur QA Doit Connaître | Postman pour les Ingénieurs QA: Du Premier Request à la Suite de Tests API