Accueil / Vérifier ce qu'il rend
Testez le vérificateur avant de croire son verdict
Un contrôle qui rend un chiffre plausible n'est pas la même chose qu'un contrôle qui rend un chiffre juste, et un contrôle défaillant échoue rarement de façon bruyante, il rend un résultat qui a l'air correct.
Un script écrit pour mesurer quelque chose, un nombre de problèmes, de caractères qui correspondent à un motif, de fichiers mal nommés, s'exécute et affiche un chiffre qui paraît plausible. Un chiffre plausible et un chiffre correct ne sont pas la même chose, et l'écart entre les deux ne s'annonce presque jamais de lui-même.
Cinq bugs, cinq chiffres faux et convaincants
Lors d'un seul audit, cinq mesures écrites maison se sont révélées fausses, chacune pour une raison différente. Une vérification de répertoire renvoyait faux sur un lien symbolique valide, comme si le dossier lié n'existait pas. Une comparaison au niveau des octets comptait mal les caractères accentués, composés de plusieurs octets. Une opération de regroupement ignorait la casse et fusionnait des éléments qui auraient dû rester distincts. Un marqueur d'ordre des octets injecté en tête de fichier faussait toute lecture ultérieure, et une expression régulière mal calée sur les fins de ligne sautait du contenu. Aucune des cinq erreurs ne s'est annoncée : chacune a produit un chiffre raisonnable, et chacune était fausse.
Ce que le point d'une expression régulière franchit vraiment
Le cas des fins de ligne se mesure plutôt qu'il ne se suppose. En JavaScript, par défaut, le point d'une expression régulière ne franchit aucun saut de ligne, ni le simple retour à la ligne des systèmes Unix ni la paire de caractères que Windows utilise. Le script pointe.js compare les deux, sur un fichier de chaque style.
node pointe.js unix.txt
point simple, sans drapeau s : false
point simple, drapeau s : true
deux points, drapeau s : false
node pointe.js windows.txt
point simple, sans drapeau s : false
point simple, drapeau s : false
deux points, drapeau s : true
Le piège propre à Windows n'apparaît qu'une fois le drapeau qui autorise le point à franchir les sauts de ligne activé : une fin de ligne Windows compte pour deux caractères, un retour chariot et un saut de ligne, et un seul point n'en couvre qu'un des deux. Sur un fichier Unix, ce même drapeau suffit puisqu'il n'y a qu'un caractère à franchir. Un auto-test qui inclut du contenu à cheval sur une fin de ligne Windows, avec le drapeau actif, attrape l'erreur que la même entrée en fin de ligne Unix ne peut pas révéler.
L'auto-test, avant de faire confiance
Le correctif coûte quelques minutes et doit tourner avant la première sortie réelle d'un script de mesure. Donnez-lui une entrée fabriquée qu'il doit absolument signaler, et une entrée propre qu'il ne doit absolument pas signaler. Faites couvrir à ces deux cas les particularités réelles de votre terrain : fins de ligne différentes, caractères accentués, liens symboliques, casse mixte. Un script incapable de classer correctement ses propres cas de test à réponse connue ne mérite aucune confiance sur des données réelles, quelle que soit la plausibilité de son chiffre.
Compter aussi les fausses alertes
Un vérificateur de liens morts a un jour signalé un lot de problèmes dont la figure qui accompagne cette leçon donne le compte exact et la part réellement fondée. La plupart des signalements venaient d'une incohérence de nommage que le vérificateur n'avait pas prévue, et deux bugs distincts de faux positifs se cachaient sous ce bruit : un marqueur d'ordre des octets pris pour un bloc de métadonnées manquant, et un exemple entre guillemets dans un bloc de code pris pour une véritable violation de style. Ces deux bugs n'ont été trouvés qu'en testant le détecteur contre des cas connus, jamais en scrutant sa sortie plus attentivement. Une fausse accusation coûte autant de confiance qu'un défaut manqué : mesurez le taux de faux positifs d'un détecteur, pas seulement ce qu'il attrape.
Faire écrire au programme lui-même son fichier de sortie évite le marqueur d'ordre des octets : sur PowerShell 5.1, la redirection et Out-File en insèrent un, invisible ; Set-Content n'en ajoute aucun mais écrit en encodage local, cassant les accents (E9, E0, E7). Remède : écriture explicite en UTF-8 sans marqueur, via WriteAllText et UTF8Encoding($false). Ce principe rejoint un vert ne prouve rien tant qu'il n'a pas été prouvé lui-même : un contrôle qui n'a pas fait ses preuves sur des cas connus ne mérite aucun crédit sur des cas réels.
Cinq échecs silencieux et l'auto-test qui les attrape
| Mode d'échec silencieux | À quoi ça ressemble | Auto-test qui l'attrape |
|---|---|---|
| Lien symbolique lu comme inexistant | Une vérification de répertoire renvoie faux sur un lien symbolique valide | Inclure un dossier lié par lien symbolique dans le cas de test propre connu |
| Comptage erroné des caractères accentués | Une comparaison au niveau des octets compte mal les caractères multi octets | Inclure des caractères accentués dans les deux cas de test |
| Marqueur d'ordre des octets injecté par PowerShell 5.1 | Sur Windows PowerShell 5.1, l'opérateur de redirection et Out-File ajoutent un marqueur invisible en tête de fichier ; Set-Content n'en ajoute aucun mais écrit en encodage local, ce qui casse les caractères accentués | Écrire explicitement en UTF-8 sans marqueur, par exemple WriteAllText avec UTF8Encoding($false), puis vérifier les premiers octets et la relecture des accents |
| Point d'une expression régulière qui ne franchit aucune fin de ligne | En JavaScript, sans le drapeau qui l'autorise, aucun contenu à cheval sur un saut de ligne n'est trouvé | Inclure du contenu à cheval sur un saut de ligne, avec le drapeau actif, dans le cas mauvais connu |
| Regroupement insensible à la casse | Une étape de regroupement fusionne des entrées qui ne diffèrent que par la casse | Inclure une paire même texte, casse différente, dans le cas mauvais connu |
Un vérificateur de liens morts, testé contre lui même
Un script de comptage reçoit un dossier de test construit pour l'exercice. Ce dossier contient un sous dossier relié par lien symbolique, ainsi que plusieurs fichiers texte au format ASCII simple. Le script parcourt l'ensemble du dossier et rend un compte qui inclut les fichiers atteints par le lien symbolique.
Écrivez en une phrase ce que ce résultat établit, et en une phrase ce qu'il n'établit pas.
Ce que cela établit : Le script compte correctement les fichiers atteints par un lien symbolique, le piège que ce dossier de test couvrait.
Ce que cela n’établit pas : Il n'établit pas que le script compte correctement des fichiers contenant des caractères accentués ou un marqueur d'ordre des octets, des pièges que ce dossier de test ne couvrait pas.
Les trois calibrages faux les plus courants
- Trop large Le script comptera désormais correctement n'importe quel dossier réel, quels que soient les caractères ou marqueurs qu'il contient.
- Trop étroit Ce résultat ne prouve rien, puisqu'un seul dossier de test a été utilisé.
- À côté Ce résultat montre que le script s'exécute plus vite que la version précédente du même script.
- Un script de mesure défaillant échoue rarement bruyamment : il rend un chiffre qui a l'air juste.
- En JavaScript, le point d'une expression régulière ne franchit aucun saut de ligne par défaut ; le piège Windows n'apparaît qu'avec le drapeau qui l'autorise, et demande deux points puisqu'une fin de ligne Windows compte pour deux caractères.
- L'auto-test se compose d'une entrée mauvaise connue à signaler et d'une entrée propre connue à ne pas signaler, toutes deux construites sur les particularités réelles du terrain.
- Le taux de faux positifs d'un détecteur se mesure au même titre que ce qu'il attrape, une fausse accusation coûtant autant de confiance qu'un défaut manqué.
- Sur Windows PowerShell 5.1, l'opérateur de redirection et Out-File injectent un marqueur d'ordre des octets invisible ; Set-Content n'en ajoute aucun mais écrit en encodage local et casse les caractères accentués, le remède mesuré étant une écriture explicitement encodée en UTF-8 sans marqueur.
Prenez un script de mesure que vous utilisez déjà, écrivez pour lui une entrée fabriquée qu'il doit signaler et une entrée propre qu'il ne doit pas signaler, ajoutez un cas limite réel de votre terrain, et confirmez les deux verdicts avant de continuer à l'utiliser.