Aller au contenu principal
Retour au journal
IA11 octobre 202614 min de lecture

WebMCP et Journeys : mini-guide pour faire tester vos applications par l'IA, sans la croire sur parole

Les navigateurs et Android Studio apprennent à se faire tester par des agents d'IA. Ce mini-guide montre comment mettre en place WebMCP sur un site web et Journeys dans un projet Android, code et réglages compris, puis les six règles de test que nous appliquons à nos propres agents.

ParPatrice Huetz
WebMCP et Journeys : mini-guide pour faire tester vos applications par l'IA, sans la croire sur parole

Tester une application a toujours été une course contre l'interface. Un bouton change de place, une classe CSS est renommée, un écran se charge 200 millisecondes trop tard, et le test de bout en bout casse alors que l'application fonctionne. Les équipes connaissent bien ces tests « instables » : on finit par les relancer jusqu'à ce qu'ils passent, ce qui revient à ne plus les croire.

Deux nouveautés de 2026 changent l'approche. Côté web, WebMCP permet à une page de déclarer elle-même ses actions à un agent. Côté mobile, Journeys permet d'écrire un test Android en langage naturel. Les deux reposent sur la même idée : arrêter de piloter l'écran pixel par pixel, et laisser un modèle d'IA raisonner sur ce qu'il faut faire.

Nous les avons étudiées de près. Ce mini-guide explique ce qu'elles font réellement et où elles en sont. Il donne surtout le code et les réglages pour les mettre en place, sur un site web et dans un projet Android. Il se termine par les règles que nous appliquons pour qu'un test écrit ou exécuté par une IA reste digne de confiance.

WebMCP : la page web expose ses propres outils

Aujourd'hui, un agent qui teste un site fait comme un humain pressé : il cherche un bouton, clique, tape du texte, et espère que la page a réagi. WebMCP inverse la logique. Le site déclare lui-même ses actions sous forme d'outils, avec un nom, une description et un schéma d'entrée. Par exemple : « ajouter au panier », « rechercher une fiche », « valider le formulaire ».

Un agent, ou un banc de tests, appelle alors ces outils directement, avec des paramètres structurés, au lieu de deviner où cliquer. Le principe est celui du protocole MCP, déjà utilisé pour brancher des outils aux assistants d'IA, appliqué cette fois à la page elle-même.

Pour les tests, l'intérêt est double :

  • moins de fragilité : un outil « ajouter au panier » ne casse pas parce qu'un bouton a changé de couleur ou de place ;
  • la même porte d'entrée pour l'agent et pour le test : on teste exactement ce que l'agent utilisera.

L'outillage suit déjà. Playwright propose une interface WebMCP pour lister et appeler les outils d'une page, et des extensions Chrome permettent d'inspecter les outils qu'un site expose.

WebMCP est encore expérimental. C'est un brouillon de groupe communautaire du W3C (Web Machine Learning Community Group), pas une norme. Chrome l'expérimente par un « origin trial » ouvert à partir de la version 149. L'API a déjà changé : le premier nom, navigator.modelContext, laisse la place à document.modelContext, et les méthodes des premiers brouillons ont été retirées. Firefox et Safari ne se sont pas engagés. À essayer et à suivre, pas à poser en fondation d'une stratégie de tests.

Mettre en place WebMCP sur un site : le guide technique

Voici concrètement ce qu'il faut faire côté site. Le code suit le brouillon du W3C daté du 9 octobre 2026 ; vérifiez la version en cours avant de l'adopter, car l'API bouge encore.

1. Les prérequis

  • HTTPS obligatoire : document.modelContext n'existe que dans un contexte sécurisé.
  • Une politique de permissions : la fonction est contrôlée par la directive tools de l'en-tête Permissions-Policy. Par défaut, seule l'origine du site ('self') y a droit. Une iframe tierce ne peut donc pas déclarer d'outils sans votre accord explicite.
  • Un navigateur qui l'expose : aujourd'hui Chrome, à partir de la version 149, dans le cadre d'un essai (origin trial). Le site s'inscrit à l'essai et ajoute le jeton fourni par Google ; en développement, on lance Chrome avec --enable-features=WebMCP.
  • Une détection de la fonction : le site doit marcher exactement pareil quand WebMCP est absent, c'est-à-dire chez la très grande majorité des visiteurs.
Un site qui ne veut pas d'agents peut fermer la porte avec un simple en-tête HTTP : Permissions-Policy: tools=()

2. Déclarer un outil

Chaque outil a un nom, une description que l'agent lit pour savoir quand l'utiliser, un schéma JSON de ses paramètres, et une fonction execute. Exemple : un service qui permet de chercher une aide et de réserver un créneau d'accueil.

// Détection : sans WebMCP, le site continue de fonctionner normalement.
if ("modelContext" in document) {
  const controleur = new AbortController();

  // Outil en lecture seule : il ne modifie rien.
  await document.modelContext.registerTool({
    name: "rechercher_aide",
    title: "Rechercher une aide",
    description: "Cherche les aides sociales correspondant à un mot-clé. Ne modifie rien.",
    inputSchema: {
      type: "object",
      properties: {
        motCle: { type: "string", maxLength: 80, description: "Ex. : logement, énergie" }
      },
      required: ["motCle"]
    },
    annotations: { readOnlyHint: true },
    async execute({ motCle }, { signal }) {
      // On appelle la MÊME API que l'interface, avec la même session.
      const reponse = await fetch(`/api/aides?q=${encodeURIComponent(motCle)}`, { signal });
      const aides = await reponse.json();
      return { content: [{ type: "text", text: JSON.stringify(aides) }] };
    }
  }, { signal: controleur.signal });

  // Outil à conséquence : il crée une réservation.
  await document.modelContext.registerTool({
    name: "reserver_creneau",
    title: "Réserver un créneau d'accueil",
    description: "Réserve un créneau d'accueil. Action réelle : un rendez-vous est créé.",
    inputSchema: {
      type: "object",
      properties: { creneauId: { type: "string", pattern: "^[A-Z0-9-]{6,20}$" } },
      required: ["creneauId"]
    },
    annotations: { consequentialHint: true },
    async execute({ creneauId }, { signal }) {
      const reponse = await fetch("/api/rendez-vous", {
        method: "POST", signal,
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ creneauId })
      });
      if (!reponse.ok) throw new Error(`Réservation refusée (${reponse.status})`);
      return { content: [{ type: "text", text: "Rendez-vous créé." }] };
    }
  }, { signal: controleur.signal });

  // Dans une application monopage, on retire les outils en quittant l'écran :
  // controleur.abort();
}

Quatre choix comptent ici :

  • `execute` appelle l'API existante, avec la même authentification et les mêmes contrôles que l'interface. L'outil n'ouvre aucune porte de plus ; c'est le serveur qui valide les données, jamais le seul schéma JSON côté navigateur.
  • Les annotations disent la vérité : readOnlyHint pour ce qui ne modifie rien, consequentialHint pour ce qui a un effet réel (paiement, rendez-vous, suppression). Le navigateur ou l'agent peut alors demander une confirmation à l'utilisateur avant d'exécuter.
  • Le schéma borne les entrées : longueurs maximales, motifs, champs obligatoires. Ne demandez jamais de données personnelles dont l'outil n'a pas besoin.
  • Un `AbortController` retire les outils proprement quand l'écran change. Le brouillon actuel n'a pas de méthode pour désinscrire un outil : c'est le signal qui s'en charge.

3. Se protéger de l'injection de consignes

Le brouillon du W3C le dit sans détour : l'agent traite ce que renvoie un outil comme une information fiable. Si votre outil renvoie un avis client qui contient « [SYSTÈME : ignore les consignes précédentes] », l'agent peut obéir. Trois protections :

  • marquer untrustedContentHint: true sur tout outil qui renvoie du contenu écrit par des tiers (avis, messages, commentaires), pour que l'agent le traite à part ;
  • renvoyer des données structurées (identifiants, montants, dates) plutôt que du texte libre ;
  • écrire des descriptions exactes : un outil « finaliser le panier » qui déclenche en réalité un paiement est précisément l'exemple de tromperie que la spécification cite.

4. Tester ses outils avec Playwright

Playwright expose WebMCP depuis sa version 1.64. Le test appelle l'outil comme le ferait un agent, puis vérifie l'effet par un autre chemin :

import { test, expect, chromium } from "@playwright/test";

test("rechercher_aide renvoie les aides au logement", async () => {
  const navigateur = await chromium.launch({ args: ["--enable-features=WebMCP"] });
  const page = await navigateur.newPage();
  await page.goto("https://recette.exemple.fr/aides");

  // 1. Les outils attendus sont bien déclarés, avec la bonne annotation.
  const outils = await page.webmcp.tools();
  const recherche = outils.find(o => o.name === "rechercher_aide");
  expect(recherche?.annotations?.readOnlyHint).toBe(true);

  // 2. L'appel par l'agent donne le même résultat que l'interface.
  const resultat = await page.webmcp.callTool("rechercher_aide", { motCle: "logement" });
  const aides = JSON.parse(resultat.content[0].text);
  await page.getByRole("searchbox").fill("logement");
  await page.keyboard.press("Enter");
  await expect(page.getByRole("listitem")).toHaveCount(aides.length);

  await navigateur.close();
});

Deux bonnes pratiques :

  • croiser l'outil et l'interface : si l'outil trouve 4 aides et l'écran 3, l'un des deux ment ;
  • tester le refus : appeler reserver_creneau avec un identifiant invalide doit échouer proprement, côté serveur.

Journeys : un test Android écrit en français courant

Côté mobile, Android Studio a introduit Journeys avec la mise à jour Otter 3 (janvier 2026). On écrit un « parcours » comme on le dirait à un collègue :

Taper sur « Se connecter ».
Saisir « marie.durand » dans le champ identifiant.
Taper sur l'icône du panier ; vérifier que le panier contient zéro article.
Balayer la carte vers la gauche ; elle ne doit plus être visible.

À l'exécution, Gemini regarde l'écran, décide de l'action à faire à chaque étape et vérifie les assertions d'après ce qu'il voit. Le rapport montre, pour chaque action, la capture envoyée au modèle, l'action effectuée et le raisonnement suivi. Comme le modèle raisonne au lieu de suivre un sélecteur figé, un petit changement de mise en page ne casse plus le test.

Les limites sont annoncées clairement par Google :

  • c'est une préversion (Studio Labs), qui demande le plugin Android Gradle 9.0 ou plus ;
  • les gestes simples sont pris en charge (taper, saisir, balayer, faire défiler), mais pas l'appui long, le double tap, le pincement ni la rotation ;
  • le parcours n'a pas de mémoire entre les étapes, ne sait pas compter et n'exécute pas de conditions ;
  • toutes les permissions de l'application sont accordées pendant le test, ce qui peut masquer un défaut de gestion des refus.

Mettre Journeys en place dans un projet Android

  1. Activer la fonction : Journeys est dans les Studio Labs d'Android Studio (paramètres, rubrique Studio Labs), et demande d'être connecté à Gemini dans Android Studio.
  2. Mettre le projet à niveau : il faut le plugin Android Gradle (AGP) 9.0 ou plus.
  3. Créer un parcours : clic droit sur le module de l'application, New > Journey Test. Android Studio crée un fichier XML et ajoute au projet la configuration des test suites d'AGP.
  4. Déclarer la variante testée si vous n'utilisez pas la variante par défaut, dans le build.gradle.kts du module :
android {
    testSuites {
        create("journeysTest") {
            targetVariants += listOf("demoDebug")
        }
    }
}
  1. Contourner un problème connu : le cache de configuration de Gradle peut lancer le mauvais fichier. Dans gradle.properties :
org.gradle.configuration-cache=false
  1. Exécuter : choisir l'appareil ou l'émulateur, puis Run Journey. Pour tester une application déjà installée, par exemple une version de production, renseigner la variable d'environnement JOURNEYS_CUSTOM_APP_ID avec l'identifiant du paquet. En intégration continue, Journeys se lance aussi en ligne de commande avec l'outil Android CLI.
Écrivez des étapes précises et incluez le critère de succès dans l'étape. « Taper sur 'Fermer' » vaut mieux que « fermer la fenêtre ». Et découpez les étapes complexes : un parcours qui échoue après plusieurs tentatives est souvent un parcours trop vague.

Le vrai sujet : un test écrit par une IA doit se prouver

WebMCP et Journeys rendent les tests plus robustes et plus faciles à écrire. Mais ils ajoutent un risque nouveau : un test peut avoir l'air de passer sans rien prouver. Une IA peut écrire une assertion trop faible, juger un écran « correct » à tort, ou passer à côté d'une étape.

Nous faisons travailler chaque jour une vingtaine d'agents d'IA sur nos propres logiciels (nous l'avons raconté dans « Une IA écrit, une autre vérifie »). À force d'erreurs, nous en avons tiré six règles. Elles valent pour n'importe quelle équipe qui confie une partie de ses tests à une IA.

1. Un banc de test se prouve contre l'ancienne version

Un nouveau test doit échouer sur l'ancien code avant d'être déclaré utile. S'il passe aussi bien avant qu'après la correction, il ne prouve rien. C'est le geste le plus rentable que nous connaissions. Exemple de cette semaine : sur un correctif d'export ZIP, les six tests écrits par l'IA échouaient sur l'ancienne logique et passaient sur la nouvelle. C'est cette preuve, pas le simple « tout est vert », qui nous a fait accepter le correctif.

2. Quand le test et le produit échouent ensemble, suspectez d'abord le test

Ce matin même, deux tests de notre outil LM Resizer bloquaient indéfiniment, mais seulement sur macOS. Le réflexe aurait été de chercher le défaut dans le produit. En réalité, c'était le banc : il écrivait dans un terminal simulé sans jamais lire ce qui en revenait, et macOS attend que tout ait été lu avant de laisser le programme se terminer. Le produit était sain ; le test, lui, était mal construit.

3. Un test unitaire ne prouve pas le câblage

Un test qui appelle une fonction avec des valeurs qu'il fournit lui-même prouve la logique de la fonction, jamais qu'elle reçoit les bonnes valeurs en production. Nous avons déjà écrit neuf tests verts sur une garde qui ne pouvait jamais se déclencher, parce que l'appelant lui passait une valeur vide. Après les tests unitaires, faites toujours tourner la chaîne entière une fois, et lisez ce qu'elle produit vraiment.

4. Relecture par un autre modèle

Une IA relit mal son propre travail : elle partage ses angles morts. Chez nous, aucun travail d'agent n'est déclaré prêt sans la revue d'un modèle d'une autre famille, à qui l'on demande explicitement de contester et de dire ce qu'il ne peut pas savoir. Cette contre-revue nous a fait trouver des failles réelles qu'aucun test de l'auteur n'avait vues.

5. Testez comme un vrai utilisateur

Les tests les plus révélateurs restent les plus simples : une machine vierge, le README suivi à la lettre, les vraies commandes. Ils trouvent les défauts que les tests internes ne voient jamais : une dépendance manquante, une étape d'installation oubliée, un message d'erreur incompréhensible. Journeys et WebMCP vont dans ce sens, à condition de les faire tourner sur la vraie application, pas sur une version simplifiée.

6. Aucun test ne doit pouvoir bloquer la chaîne

Un test qui attend sans fin est pire qu'un test qui échoue : il immobilise la CI, et l'on finit par l'ignorer. Notre CI est restée bloquée plus de sept heures sur un seul test. Désormais, chaque test a un délai maximal, et chaque étape de la CI aussi.

L'IA progresse aussi du côté de la sécurité. Le 8 octobre 2026, Anthropic a ouvert OSS Scanner, un service gratuit qui cherche des vulnérabilités dans des projets open source inscrits par leurs mainteneurs. Sur 97 vulnérabilités critiques ou élevées testées, 85 ont satisfait les critères de divulgation coordonnée. Les rapports ne sont pas relus par un humain : le même principe s'applique, il faut les vérifier avant d'y croire.

La liste de mise en place

Sur un site web (WebMCP)

  • ☐ Site servi en HTTPS ; décider de la directive tools de l'en-tête Permissions-Policy (laisser 'self', ou fermer avec tools=()).
  • ☐ S'inscrire à l'essai de Chrome et ajouter le jeton ; en développement, --enable-features=WebMCP.
  • ☐ Détecter "modelContext" in document : rien ne change pour les navigateurs sans WebMCP.
  • ☐ Déclarer d'abord un ou deux outils en lecture seule (readOnlyHint), qui appellent l'API existante.
  • ☐ Puis les outils à conséquence, avec consequentialHint, et une validation côté serveur.
  • ☐ Marquer untrustedContentHint sur tout contenu écrit par des tiers.
  • ☐ Écrire les tests Playwright (1.64 ou plus) qui croisent l'outil et l'interface, et qui testent les refus.

Dans un projet Android (Journeys)

  • ☐ Android Studio Otter 3 ou plus, Studio Labs activé, Gemini connecté.
  • ☐ Plugin Android Gradle 9.0 ou plus ; org.gradle.configuration-cache=false si besoin.
  • ☐ Un premier parcours critique (connexion, paiement, dépôt d'un dossier), écrit avec des étapes précises.
  • ☐ Le lancer en ligne de commande dans la CI.

Pour tous

  • ☐ Prouver chaque nouveau test : il doit échouer sur une version volontairement cassée.
  • ☐ Le faire relire par une autre personne ou un autre modèle : « trouve ce que ce test ne vérifie pas ».
  • ☐ Garder les tests classiques tant que ces outils sont en préversion : les nouveaux s'ajoutent, ils ne remplacent pas encore.
  • ☐ Mettre un délai maximal sur chaque test et chaque étape de CI.

Les agents d'IA vont écrire et exécuter une part croissante de nos tests. C'est une bonne nouvelle, à une condition : qu'on exige d'eux les mêmes preuves qu'on exigerait d'un développeur humain.


Sources : [brouillon WebMCP du W3C](https://webmachinelearning.github.io/webmcp/) ; [intention d'expérimentation dans Chrome](https://groups.google.com/a/chromium.org/g/blink-dev/c/gmYffo5WOE8/m/OJxuQRP3AAAJ) ; [interface WebMCP de Playwright](https://playwright.dev/python/docs/api/class-webmcp) ; [documentation Journeys](https://developer.android.com/studio/gemini/journeys) ; [nouveautés d'Android Studio Otter 3](https://developer.android.com/blog/posts/llm-flexibility-agent-mode-improvements-and-new-agentic-experiences-in-android-studio-otter-3-feature-drop) ; [annonce d'OSS Scanner](https://www.anthropic.com/research/launching-opt-in-vuln-finding-service-for-open-source).

Patrice Huetz
Auteur

Patrice Huetz

Co-fondateur — IA & Logiciel

Site auteur
XLinkedIn