Mocking réseau pour tests de navigateur autorisés
Rendez les tests de navigateur autorisés déterministes avec des réponses réseau contrôlées, sans confondre mock et production.
Vous voulez la documentation structurée pour Démarrage ?
Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.
Le mocking réseau est pertinent lorsque le test possède la page et la dépendance applicative testée. Une réponse contrôlée rend reproductibles un chargement, une liste vide, une erreur de validation ou une panne temporaire sans attendre un service distant. Cette limite appartient au contrat du test : le mock est un double pour une dépendance autorisée, pas un moyen de modifier un site tiers, de contourner une politique ou d'affirmer que la production s'est comportée de la même façon.
Décrivez d'abord le contrat visible : route, méthode et forme de requête, état attendu et preuve autorisée. Décidez quelle dépendance appartient à votre équipe et quelle intégration réelle doit être vérifiée séparément. Consultez le guide Playwright et le guide des téléchargements et téléversements pour le cycle du navigateur et les artefacts. La documentation du mocking Playwright et les pratiques Selenium décrivent les mécanismes, mais aucune réponse synthétique ne prouve le comportement d'un service distant.
Délimiter la propriété
Interceptez une seule requête appartenant au scénario, avec une identité synthétique, une origine de test et un motif assez étroit pour éviter l'analytique, l'authentification, la télémétrie et les ressources étrangères. Le handler vérifie la méthode et les champs utiles, renvoie une réponse documentée et conserve seulement une catégorie de résultat. N'écrivez pas de cookies, de jetons, d'en-têtes d'autorisation, de corps complets, de texte de page ou de corps de réponse de production dans le journal.
Séparez le chemin de production. Placez les handlers dans le code de test ou un stub réservé aux tests, activez-les avec une option explicite et faites échouer le test si cette option apparaît dans une version de production. Le résultat doit nommer le scénario afin qu'un reviewer distingue une réponse synthétique d'une intégration réelle. Si un service worker ou le cache empêche la requête d'arriver, documentez ce chemin. Un handler qui ne reçoit aucune requête décrit le parcours du navigateur, il ne prouve pas que le service a été appelé.
Définir un fixture déterministe
Avant le handler, notez quatre faits simples :
- Entrée : enregistrement synthétique, route, méthode et schéma de réponse possédés par le test.
- Changement : une condition contrôlée, par exemple le statut 503, une liste vide ou un délai borné.
- Observation : état visible pour l'utilisateur et compteur court des correspondances.
- Nettoyage : suppression de la route, fermeture du contexte et état de conservation des artefacts.
Une seule condition modifiée rend l'échec explicable. Si le même fixture change aussi l'authentification, les retries, le cache et les données de base, une assertion réussie ne permet plus de savoir quel contrat a été exercé. Versionnez le schéma avec le test et choisissez des valeurs impossibles à confondre avec un client. Un fixture peut représenter un incident upstream, mais son nom doit préciser qu'il est synthétique.
Choisir l'API réseau minimale
Cette matrice associe une question de test à une surface d'interception et à sa limite de preuve. Utilisez une ligne par contrat, sans handler attrape-tout.
| Besoin | Playwright | Selenium/WebDriver | Limite de preuve |
|---|---|---|---|
| Retourner un JSON connu | page.route('**/api/items', route => route.fulfill({ json })) | Proxy de test ou endpoint stub possédé, configuré avant le driver | État rendu pour la réponse synthétique |
| Exercer une erreur serveur | route.fulfill({ status: 503, body: ... }) | Endpoint stub avec le statut documenté | Interface d'erreur et reprise, pas santé du service |
| Simuler la latence | route.fulfill({ delay: 250, ... }) ou stub contrôlé | Proxy ou stub qui retarde seulement la route nommée | Transition de chargement et gestion du timeout |
| Observer sans modifier | route.continue() et compteur réduit | Journal du proxy avec métadonnées minimales | Chemin de requête, pas succès d'autorisation |
| Garantir le nettoyage | page.unroute() dans finally et fermeture du contexte | Arrêter le proxy possédé et quitter le driver | Aucun handler ou état de worker ne fuit vers le test suivant |
N'utilisez pas une interception **/* sauf si le test vérifie explicitement une politique réseau. Un handler large peut masquer des ressources manquantes et rendre le succès sans rapport avec le parcours réel. Pour une route, vérifiez la méthode, renvoyez un petit fixture et laissez les autres requêtes continuer ou échouer selon le contrat. Une requête inattendue doit produire un échec visible, jamais une réponse inventée.
Conserver un fixture d'échec reproductible
Le fixture change une condition et nomme le résultat visible attendu. Cet exemple Playwright renvoie une panne synthétique, conserve la première assertion et supprime toujours la route avec le contexte :
const context = await browser.newContext();
const page = await context.newPage();
let matched = 0;
await page.route('**/api/items', async route => {
matched += 1;
await route.fulfill({
status: 503,
contentType: 'application/json',
body: JSON.stringify({ code: 'owned-test-outage' }),
});
});
try {
await page.goto('http://test.local/items');
await expect(page.getByRole('alert')).toHaveText('Items are temporarily unavailable');
expect(matched).toBe(1);
} finally {
await page.unroute('**/api/items');
await context.close();
}
Ce fixture prouve que la page affiche l'erreur et la reprise documentées pour cette réponse. Il ne prouve pas qu'un upstream réel renvoie 503, que les retries sont sûrs, que l'autorisation a réussi ou qu'un enregistrement distant n'a pas changé. Gardez le code synthétique et le schéma près du test. Ne copiez jamais de secrets de production dans un fixture.
Si la configuration, l'assertion et le nettoyage peuvent échouer, conservez la première erreur et rapportez le nettoyage dans un champ séparé. Une erreur de fermeture ultérieure ne doit pas remplacer la cause du défaut. Un retry crée un nouveau contexte et une nouvelle tentative ; un succès ultérieur ne prouve pas que la première requête n'a eu aucun effet distant.
Décider quand le réalisme l'emporte
Le mocking est un choix limité. Utilisez cette table avant d'ajouter un handler :
| Objectif du test | Mock ? | Décision |
|---|---|---|
| Chargement, vide, validation ou panne de l'interface possédée | Oui | Entrée déterministe et contrat répétable |
| Contrat client/serveur et sérialisation | Généralement non ; intégration possédée | Le mock ne détecte pas la dérive de schéma ou de transport |
| Paiement, identité ou mutation irréversible | Non pour la preuve finale | Le service autorisé doit confirmer le résultat distant |
| Reproduire un incident upstream connu | Oui, avec fixture nommé | Condition synthétique explicite et révisable |
| Sonder ou modifier un tiers | Non | Hors propriété et autorisation |
Associez des tests mockés fréquents à quelques intégrations réelles approuvées. Le test mocké tourne à chaque changement ; l'intégration vérifie que route, en-têtes, schéma, autorisation et politique du service concordent. Séparez noms et reçus afin qu'un succès synthétique ne masque pas un défaut réel. Une réponse visible dans le navigateur ne prouve ni facturation, ni changement de compte, ni suppression de données, ni disponibilité distante sans preuve du propriétaire du service.
Isoler contextes, données et artefacts
Créez un BrowserContext neuf lorsque cookies, stockage, permissions, cache ou service workers influencent la route. Chaque worker reçoit un répertoire d'artefacts privé et des identifiants synthétiques. Le contexte empêche les fuites d'état géré par le navigateur, mais n'isole ni une base partagée, ni une file, ni un proxy partagé. Utilisez des enregistrements indépendants ou sérialisez la mutation avec une opération prévue par l'application.
Considérez les fichiers de fixture et les étiquettes de route comme des entrées possédées. Une base en lecture seule peut être copiée dans un répertoire de worker, mais un résultat partiel ne doit pas remplacer la base lue par un autre worker. Séparez captures, traces et compteurs, puis appliquez la politique de rétention habituelle. Un reçu court contient seulement scénario, route correspondante, classe de réponse, résultat visible et état du nettoyage.
Le nettoyage appartient au finally : supprimez la route, fermez pages et contextes, arrêtez un proxy possédé et rapportez l'échec à côté de l'assertion. Si un service worker ou le cache sert une autre réponse, notez ce chemin et modifiez volontairement la préparation du fixture. N'élargissez pas l'interception pour forcer une correspondance.
Séparer production et tests
Utilisez un hostname de test ou un mode de test fourni par l'application, des identités synthétiques et un magasin de données distinct lorsque c'est possible. Rendez l'activation du mock explicite dans la configuration du runner et dans les journaux CI. La version de production ne doit pas importer les handlers de test, et un smoke check de production doit échouer fermé si une option de test est présente. C'est une frontière de déploiement, pas une convention de nommage.
Lorsqu'une intégration réelle est requise, utilisez le compte approuvé par le propriétaire du service et sa politique de conservation. Ne réutilisez pas un reçu mock comme preuve de cette intégration. Comparez le même contrat visible, puis étiquetez les faits issus du navigateur et ceux issus du service. Si la route réelle est indisponible, consignez la condition externe au lieu de la remplacer par un succès synthétique.
Capacité et limite de BotBrowser
BotBrowser fournit des BrowserContexts isolés pour répéter un scénario autorisé avec cookies, stockage et permissions séparés, mais ne vérifie pas la base distante et ne garantit aucun effet de service.
BotBrowser peut fournir un BrowserContext isolé avec un état géré par le navigateur séparé pour un test autorisé. Cela aide un fixture réseau à démarrer avec des cookies, un stockage, des permissions ou un état de service worker connus. BotBrowser ne décide pas quelles routes un test peut intercepter, ne transforme pas le trafic tiers en trafic possédé et ne vérifie ni base distante, ni facturation, ni autorisation, ni effet secondaire. BotBrowser ne garantit pas la disponibilité de production ni les résultats distants. Le propriétaire du test fournit les données synthétiques, contrôle le handler, ferme le contexte et demande au propriétaire de l'application les preuves hors de la frontière navigateur.
Gardez capacité et limite dans le même rapport. Notez le but du contexte, les versions navigateur et framework, la route correspondante, la classe de réponse, le résultat visible et le reçu de nettoyage. Précisez que le résultat vient d'une dépendance synthétique. Un succès mocké ne prouve ni disponibilité de production, ni autorisation, ni transaction métier. Un contexte propre ne prouve pas non plus la révocation d'une session serveur ou le vidage d'une file distante.
Revoir la frontière avant fusion
Vérifiez que le handler correspond à une route possédée, que le fixture ne change qu'une condition, que les requêtes non correspondantes suivent une politique intentionnelle et que le nettoyage s'exécute après les erreurs de configuration et d'assertion. Exécutez un succès mocké, un échec forcé et une intégration réelle approuvée lorsque le contrat l'exige. Inspectez l'étiquette de route et le reçu, jamais un corps de requête complet.
Demandez la confirmation de quatre non-déclarations : le fixture ne modifie pas un tiers ; la réponse ne prouve pas la santé de l'upstream ; l'isolation du navigateur ne supprime pas les données serveur ; et un retry n'efface pas l'incertitude de la première tentative. Les preuves réseau restent ainsi utiles, privées et proportionnées au comportement testé.
Définissez la propriété de la route avant sa syntaxe. Une URL peut appartenir à un fournisseur ou à une autre équipe. Notez le propriétaire et l'environnement approuvé. Si la propriété est incertaine, gardez la requête dans une intégration approuvée et vérifiez seulement le comportement autorisé.
L'authentification demande la même frontière. Utilisez des sessions synthétiques, représentez les rôles approuvés et ne copiez pas de session client. Un 401 ou 403 mocké vérifie l'interface, mais ne prouve pas la décision d'un moteur réel.
Choisissez volontairement le traitement du cache. Le vider stabilise le fixture ; le conserver vérifie une réponse mise en cache. Notez le choix et la correspondance de route. Si le cache répond avant le handler, gardez cette observation sans élargir le motif.
En parallèle, chaque worker possède son reçu, son fichier temporaire et son enregistrement synthétique. Le contexte protège l'état navigateur, mais les données d'application ont besoin d'une clé indépendante ou d'une sérialisation approuvée.
Rendez la correspondance explicite : méthode HTTP, chemin et paramètres du scénario. Une route pour toutes les méthodes peut transformer une écriture en réponse synthétique. Une règle sans version peut masquer une mise à jour. Des prédicats courts rendent la revue et les requêtes inattendues visibles.
Les classes de réponse font partie du contrat. Le succès contient les champs nécessaires à la page et l'erreur suit la forme documentée. Des champs supplémentaires cachent une dépendance accidentelle ; des champs absents créent un contrat non documenté.
Rendez le temps observable sans fragiliser le test. Un délai borné exerce le chargement, mais l'assertion attend une transition et non un sommeil fixe. Notez le délai dans le fixture et distinguez un timeout attendu d'une route jamais reconnue.
Utilisez un reçu commun aux mocks et intégrations : scénario, route, méthode, classe, état visible, compteur et nettoyage. N'y mettez ni identifiants, ni cookies, ni corps complets, ni texte privé. Le reviewer compare ainsi navigateur et service sans confusion.
Les retries demandent une assertion propre. Chaque tentative est nouvelle et conserve le résultat initial. Si la première requête a pu atteindre un service réel, notez l'incertitude. Le mock vérifie le flux ; seule l'intégration approuvée établit l'effet distant.
Gardez le fixture près de l'assertion qu'il explique. Nommez la condition synthétique, liez le contrat visible et documentez le contrôle réel du transport et du service.
L'authentification demande aussi une frontière explicite. Utilisez des sessions synthétiques, définissez les rôles approuvés et ne copiez pas de session client. Un 401 ou 403 mocké vérifie l'interface, mais ne prouve pas une décision réelle.
Choisissez la politique de cache. Le vider stabilise le fixture et le conserver teste une réponse mise en cache. Notez le choix et gardez l'observation si le cache répond avant le handler.
En parallèle, chaque worker possède son reçu, son fichier temporaire et son enregistrement synthétique. Le contexte protège l'état navigateur, mais les données applicatives exigent une clé indépendante ou une sérialisation approuvée.
Sources
Articles Connexes
Faites passer BotBrowser de la recherche à la production
Utilisez ces guides pour comprendre le modèle, puis passez à la validation multi-plateforme, aux contextes isolés et au déploiement navigateur prêt pour l'échelle.