Test Basé sur des Preuves
Enregistrez une preuve annotée du comportement, puis attachez-la à la PR et au ticket du suivi.
L'enregistrement est la capture de votre test de l'application via l'utilisation de l'ordinateur : démarrez l'enregistreur, puis utilisez l'application vous-même — cliquez, tapez, naviguez — à travers chaque cible de test. Chaque action dans la vidéo est le test effectué en direct ; l'enregistrement n'a aucune valeur comme preuve à moins qu'il ne montre cette session interactive. Si l'environnement ne dispose pas d'outils d'utilisation de l'ordinateur mais qu'une interface graphique existe, utilisez cua-driver pour piloter l'application (voir ci-dessous) — il s'agit toujours de votre session en direct.
L'enregistreur inclus, scripts/evidence.py, capture l'affichage avec FFmpeg sur Linux, macOS et Windows, horodate chaque annotation que vous ajoutez pendant les tests, les grave dans la vidéo à l'arrêt, et vérifie le résultat avec ffprobe. Il écrit evidence.mp4, report.md et manifest.json dans le dossier de session.
Entrées
- Cibles de test (obligatoire) : Les comportements/flux à vérifier, formulés comme des déclarations testables.
- PR / issue (facultatif) : Où publier la preuve. Si omis, livrer uniquement au demandeur.
L'enregistreur
EVIDENCE ci-dessous désigne le chemin vers scripts/evidence.py dans le dossier de cette compétence (où que la compétence soit installée, par exemple ~/.claude/skills/evidence-driven-testing/scripts/evidence.py). Il nécessite uniquement Python 3 et FFmpeg.
-
Vérification préalable :
python3 $EVIDENCE doctor— vérifieffmpeg,ffprobe,libx264et le filtreass(ready), puis quelle source de capture d'écran fonctionne sur cette machine (capture_readyet la sourceautochoisira). Se termine avec un code non nul uniquement lorsque la chaîne d'outils est manquante ; lisezcapture_readyavant d'enregistrer. -
Plateformes (
--source autochoisit la première disponible) :OS Source Nécessite Linux X11 / XWayland x11(x11grab)DISPLAYdéfiniLinux Wayland wayland(wf-recorder)WAYLAND_DISPLAYdéfini,wf-recorderdans le PATH, et un compositeur confirmé pour supporter wlr-screencopy — soit un connu des wlroots (Sway, Hyprland, river, Wayfire, labwc, dwl, niri) soit vérifié viawayland-info. GNOME et KDE Wayland ne peuvent pas être capturés de cette manière ;doctorle dit. Utilisezx11via XWayland pour les applications X11, ou un enregistreur de repli.--source waylandforce toujours cette optionmacOS avfoundationAutorisation d'enregistrement d'écran accordée au terminal / à l'application hôte de l'agent ; doctorliste les index d'écran pour--screen-indexWindows gdigrabtoute version standard de ffmpeg ; powershellpour les vérifications de processusLa capture est en plein écran par défaut ;
--geometry LxHet--offset X,Yrecadrent une région sur x11, wayland et gdigrab. XWayland ne voit que les fenêtres X11, donc préférez la sourcewaylandlorsque l'application testée est native Wayland. -
Capture brute résistante aux pannes : l'enregistrement brut est en MPEG-TS (
raw.ts), donc si l'enregistreur est tué brutalement ou plante, ce qui a été capturé peut encore être analysé et rendu.stopremuxe ou ré-encode en un fichier standardevidence.mp4. -
Fonctionnement de l'arrêt : sur Linux, l'enregistreur est signalé via un pidfd. Sur macOS et Windows,
startlance un petit processus superviseur qui possède le processus enfant ffmpeg, etstoplui demande (viastop.requestdans le dossier de session) d'interrompre, puis de terminer, puis de tuer ; il écritrecorder-exit.jsonlorsque c'est fait. Rien ne signale jamais un PID brut, donc un PID recyclé ne peut pas être touché. Si le superviseur meurt alors que l'enregistreur est toujours en cours d'exécution,stoprefuse et vous indique quel PID arrêter manuellement. S'il est mort avant même d'enregistrer quel processus il a démarré,stopreste bloqué jusqu'à ce que vous ayez vérifié vous-même la présence d'un enregistreur errant et relancé avec--accept-untracked-recorder; le rapport porte alors cette mention. -
Enregistreurs de repli lorsque
doctorne signale aucune source de capture (par exemple Wayland sans wf-recorder) :cua-driver recording start <dir>/stop(voir la section cua-driver), ou l'enregistreur du système d'exploitation (macOS :screencapture -v out.mov). Sur ces chemins, il n'y a pas de superposition d'annotations, donc conservez le protocole d'annotation sous forme de fichiers — unassertions.mdlistant chaquesetup/test_start/assertionavec son résultat et l'horodatage vidéo approximatif, exactement comme dans le chemin sans tête. -
Ne présentez jamais
--source test(le générateur de motifs synthétiques) comme preuve d'interface utilisateur. Il existe pour tester la chaîne d'outils ; lestests/test_evidence.pydu dépôt l'utilisent.
Instructions
1. Préparez l'écran
- Maximisez la fenêtre du navigateur/de l'application ; fermez les popups, notifications et panneaux supplémentaires.
- Naviguez vers l'état de départ (connecté, page correcte) AVANT l'enregistrement, sauf si la configuration elle-même est testée.
- Notez la révision exacte testée :
git rev-parse HEADetgit branch --show-current(ou l'URL de déploiement) — l'enregistreur les grave dans le rapport.
2. Démarrez l'enregistrement
-
Commencez l'enregistrement d'écran avant la première action significative :
python3 $EVIDENCE start \ --output .artifacts/<nom-de-la-tâche> \ --title "<ce qui est vérifié>" \ --commit "$(git rev-parse HEAD)" --branch "$(git branch --show-current)" \ --environment "<OS / navigateur / affichage / déploiement>"Il affiche du JSON avec un chemin
sessionet lasourcechoisie ; conservez le chemin (SESSION=...) pour chaque commande ultérieure. La source est détectée automatiquement et tout l'écran est capturé ; passez--source,--geometry,--offset,--display/--xauthority(X11),--screen-index(macOS) ou--output-name(Wayland) uniquement lorsquedoctorou la situation l'exige. -
Ajoutez une annotation
setupdécrivant le contexte de départ :python3 $EVIDENCE annotate "$SESSION" --type setup \ --message "Connecté, navigation vers la page des connecteurs"
3. Test via l'utilisation de l'ordinateur, en annotant au fur et à mesure
-
Effectuez chaque interaction via l'utilisation de l'ordinateur sur l'application en direct — l'enregistrement capture votre session, donc le test et la preuve sont le même acte. Travaillez à un rythme visible : laissez l'interface utilisateur se stabiliser après chaque action pour que les changements d'état soient visibles dans la vidéo.
-
Au début de chaque test nommé, ajoutez une annotation
test_startdans le style Jest :python3 $EVIDENCE annotate "$SESSION" --type test_start \ --message "Il devrait exécuter l'outil directement lorsque l'autorisation est 'toujours'" -
Après chaque vérification, ajoutez une annotation
assertionavec--result passed,failedouuntested:python3 $EVIDENCE annotate "$SESSION" --type assertion --result passed \ --message "L'outil s'est exécuté sans invite d'autorisation" -
Règles pour les assertions :
- Une assertion par changement d'état significatif — consolidez, n'annotez pas par libellé d'interface utilisateur.
- Utilisez des assertions "Precondition : ..." pour établir l'état de départ.
- Restez en dessous de 80 caractères, à fort signal (l'enregistreur rejette les messages plus longs).
- Si un test ne peut pas être exécuté (prérequis manquant, fenêtre d'authentification expirée), marquez-le
untestedavec la raison — ne l'ignorez jamais en silence. - L'horodatage enregistre le moment où vous avez affirmé, pas si c'était vrai — regardez l'écran avant de choisir
passed.
4. Arrêtez et révisez
-
Arrêtez l'enregistrement après la dernière assertion :
python3 $EVIDENCE stop "$SESSION"Cela arrête la capture (en douceur, pour que l'enregistreur vide le buffer ; ne s'intensifie que s'il ignore la demande), grave les annotations dans
evidence.mp4, analyse le résultat et écritreport.mdetmanifest.jsonà côté. Il affiche"verified": trueen cas de succès ; si le rendu échoue, la session est marquéefinalization_failed— corrigez la cause signalée et relancezstop(une nouvelle tentative ne signale pas l'enregistreur deux fois). Si le processus de l'enregistreur ne peut plus être signalé en toute sécurité (il est mort, ou son PID appartient maintenant à un autre processus), la session est marquéerecorder_lost. Relancerstopfinalise la vidéo capturée, mais uniquement une fois que le processus de l'enregistreur est confirmé comme terminé — s'il est toujours vivant, arrêtez-le d'abord, sinon la vidéo serait rendue pendant qu'elle est encore en cours d'écriture. -
Confirmez que l'enregistrement a capturé les moments clés avant de partager : extrayez une image à chaque horodatage d'assertion (
ffmpeg -ss <t> -i evidence.mp4 -frames:v 1 frame.png) et vérifiez que l'état et le libellé sont visibles. -
Remplissez la section Caveats de
report.md; ne laissez jamais l'espace réservé.
5. Publiez la preuve
report.mdest le rapport : ce qui a été testé, l'environnement + le commit exact, réussite/échec par test, mises en garde. Étendez-le plutôt que de le réécrire de zéro.- Publiez la vidéo + le résumé en tant que commentaire de PR (intégrez dans la description de PR si c'est votre PR).
gh pr commentne peut pas joindre une vidéo locale — téléchargezevidence.mp4via la boîte de commentaire de la PR dans un navigateur authentifié, ou téléchargez-la sur un hôte et créez un lien (par exemple les adaptateurs de téléchargementbefore-and-after). Rouvrez le commentaire et confirmez que la vidéo se lit avant de prétendre qu'elle est publiée. - Attachez la même vidéo au ticket du suivi (Linear/Jira) avec un résultat d'une ligne.
- Envoyez le rapport + l'enregistrement au demandeur.
Garde-fous
- La vidéo doit montrer la session de test réelle en cours d'exécution en direct. Ne présentez jamais de lecture scriptée, de clips assemblés ou de séquences synthétiques comme un enregistrement ; si l'environnement manque d'outils d'utilisation de l'ordinateur mais qu'une interface graphique existe, pilotez via
cua-driver; sans interface graphique du tout, utilisez plutôt le chemin sans tête. - N'enregistrez jamais une fenêtre à moitié couverte ou en mosaïque — maximisez d'abord.
- N'enregistrez jamais un écran affichant des secrets, tokens, données clients ou détails de paiement ; si un flux les nécessite, marquez-le
untestedet expliquez pourquoi. - Lors de la vérification d'un correctif, montrez ou référencez l'ancien échec en même temps que le nouveau succès.
- Indiquez toujours le commit/branche/déploiement exact testé.
Pas d'outils d'utilisation de l'ordinateur ? Pilotez avec cua-driver (interface graphique disponible)
Lorsqu'un affichage existe mais que l'agent n'a pas de capacité d'utilisation de l'ordinateur intégrée, utilisez cua-driver (macOS / Windows / Linux) comme actionneur. C'est toujours vous qui testez l'application en direct — la règle d'enregistrement reste inchangée ; seul le mécanisme d'entrée diffère.
- Vérifiez la configuration avec
cua-driver doctoravant d'enregistrer. Si une compétencecua-driverest installée, lisez-la et suivez son protocole — l'invariant "instantané avant action" est obligatoire. - Bouclez par interaction :
launch_app→get_window_state(arbre d'accessibilité + capture d'écran) → agissez viaelement_token(click,type_text,press_key) →verify_statepour la postcondition attendue. Chaque vérificationverify_statecorrespond 1:1 à une annotationassertion. - Partout où
doctorsignalecapture_ready: yes, continuez à utiliser l'enregistreur inclus ci-dessus pour la vidéo et les annotations ; cua-driver fournit uniquement l'entrée. - Sinon,
cua-driver recording start <répertoire-de-sortie>/cua-driver recording stopest l'enregistreur (le répertoire de sortie est obligatoire, et le démon doit être en cours d'exécution :cua-driver serve). La capture vidéo est activée par défaut et finalisée en<répertoire-de-sortie>/recording.mp4à l'arrêt — mais sur Windows/Linux, elle appelle ffmpeg, donc un ffmpeg ou un affichage manquant ne produit que les dossiers de trajectoire par tour (captures d'écran avant/après,action.json,click.png), pas de vidéo. Après l'arrêt, vérifiez querecording.mp4existe avant de le citer ; s'il est absent, corrigez l'enregistreur ou présentez les captures d'écran avant/après par tour comme des captures numérotées selon le protocole sans tête. - Si aucune superposition d'annotation n'est disponible sur ce chemin, conservez le protocole sous forme de fichiers : un
assertions.mdlistant chaquetest_start/assertionavec son résultat, exactement comme dans le chemin sans tête.
Chemin sans tête (pas d'interface graphique disponible)
Lorsque l'agent n'a pas de bureau à enregistrer, gardez la même discipline d'assertion ; remplacez l'enregistreur par une capture scriptée :
-
Sauvegardez tout dans
.artifacts/<nom-de-la-tâche>/(dans gitignore — les preuves sont téléchargées, jamais commitées). Conservez le script de capture à côté des captures pour que l'exécution soit reproductible. -
Captures d'écran : l'interface en ligne de commande
before-and-after(@vercel/before-and-after) capture des URL ou des éléments et ses paires alimentent directement les intégrations de PR. Dans les conteneurs/VM où Chrome échoue avec "No usable sandbox", définissezAGENT_BROWSER_ARGS="--no-sandbox". -
Vidéo / flux multi-étapes : un script Playwright unique, exécuté sans ajouter Playwright aux dépendances du projet :
npx --yes --package=playwright node record.mjs(Un simple
npx playwright node record.mjséchoue —noden'est pas une commande CLI Playwright ;--package=playwrightest ce qui met le module sur le chemin.)record.mjsminimal :import { chromium } from "playwright"; const browser = await chromium.launch(); const context = await browser.newContext({ recordVideo: { dir: ".artifacts/<nom-de-la-tâche>/" }, }); const page = await context.newPage(); await page.goto("http://localhost:3000/chemin-sous-test"); // ...pilotez le flux, un changement d'état significatif par étape... await context.close(); // finalise le .webm await browser.close();Réduisez ou compressez avec ffmpeg si le fichier est volumineux.
-
Le protocole d'annotation devient des fichiers : numérotez les captures dans l'ordre du test avec l'assertion dans le nom —
01-precondition-connecté.png,02-il-sauvegarde-au-blur-passé.png— et conservez unassertions.mddans le dossier des artefacts listant chaquetest_start/assertionavec son résultat (passed/failed/untested+ raison).
Les modifications non-UI nécessitent aussi des preuves
- API / performance : une sonde scriptée avec des nombres mesurés — nombre de requêtes par phase, latence avant/après — capturée dans
probe-output.txt. - Rendu / canvas / shader : images rendues plus assertions de pixels (valeurs de différence), examinées à l'œil et sauvegardées en PNG.
- Comportement de l'agent : l'extrait de transcription pertinent montrant l'appel d'outil et la réponse.
- Corrections de bugs : reproduisez et capturez l'échec avant d'écrire le correctif — cette capture est la moitié "avant" d'une paire avant/après.
Hygiène de capture
- Confirmez que le serveur que vous sondez exécute votre code (bon port, bon processus), surtout lorsque plusieurs agents partagent une machine :
lsof -i :<port>— ou là oùlsofn'est pas installé,ss -ltnp "sport ...".