Aller au contenu principal
La newsletter arrive ! Premier envoi très bientôt : laissez votre adresse pour la recevoir.

La QA, c'est quoi ? Demandez aux 8,5 millions d'écrans bleus.

Écrans bleus CrowdStrike, panne Cloudflare, scandale Horizon : ce que coûte une QA absente, et la carte des outils qui protègent un projet web.

9 min de lecture
Sommaire · 6

Le 18 novembre 2025, à 11h20 UTC, une grosse partie du web s'arrête de répondre. Erreurs 5xx en rafale, tableaux de bord inaccessibles, authentification morte : le réseau de Cloudflare tousse, et il faudra plus de trois heures pour rétablir le gros du trafic.

La cause tient en une phrase de leur post-mortem : un fichier de configuration a doublé de taille, et une ligne de Rust a refusé la surprise. Un unwrap(), autrement dit « fais-moi confiance, ça ne peut pas échouer ». Ça a échoué.

Ce billet ouvre une série sur la QA, l'assurance qualité logicielle. On y pose ce que le mot recouvre, ce que son absence a coûté dans quatre pannes documentées, puis la carte des familles d'outils qui montent la garde sur un projet réel : ce blog. Chaque famille aura ensuite ses propres billets.

La QA, c'est quoi au juste

QA, pour Quality Assurance : assurance qualité. Le sigle recouvre deux réalités qui se croisent sans se confondre.

D'un côté, un métier : des testeurs, des plans de test, des campagnes de recette, une équipe dédiée dans les structures qui peuvent se l'offrir. De l'autre, une discipline outillée : tout ce qu'un projet met en place pour qu'une erreur connue ne puisse plus atteindre la production. Cette série parle de la seconde, celle qui reste quand on développe seul ou en petite équipe.

Un point pour éviter les malentendus : la QA ne démontre jamais qu'un logiciel est correct. Dijkstra le formulait dès 1972 : les tests savent montrer la présence de bugs, pas leur absence.

En revanche, on peut interdire des classes entières d'erreurs. Le typage strict interdit la classe « ce n'était pas le type attendu ». Un test de non-régression interdit la classe « ce bug précis revient ». Ce principe vaut aussi pour la sécurité : plus loin, un scanner de secrets interdira à une clé d'API de finir dans l'historique git.

L'image qui servira toute la série : un filet. Chaque outil est une rangée de mailles. Aucune maille n'arrête tout ; chacune arrête une famille de chutes que les autres laissent passer. Monter une QA, c'est tisser ce filet rangée par rangée, puis le tendre au dernier moment utile : entre le développeur et la production.

Quatre pannes, quatre garde-fous manquants

Le 19 juillet 2024, CrowdStrike pousse une mise à jour de contenu vers son agent de sécurité : le Channel File 291. Le capteur attendait 20 champs, le fichier en portait 21. Lecture mémoire hors des limites, dans un driver kernel : écran bleu au démarrage, et la machine ne revient pas seule.

Microsoft estimera 8,5 millions de machines Windows touchées, moins de 1 % du parc mondial. Assez pour des milliers de vols annulés et des hôpitaux qui déprogramment.

L'analyse de cause racine pointe un bug du validateur de contenu, qui a laissé passer le fichier, et un déploiement mondial d'un coup, sans vagues progressives. La maille manquante : traiter les données qu'on déploie avec la même méfiance que le code qu'on livre.

Le 18 novembre 2025, chez Cloudflare, la scène d'ouverture. Un changement de permissions sur une base ClickHouse fait remonter des colonnes en double dans la requête qui génère le fichier de features anti-bots. Le fichier double de taille, dépasse une limite préallouée de 200 entrées (l'usage courant tournait autour de 60), et le code qui le charge fait unwrap(). Panique du proxy, 5xx en cascade.

Dans ses remédiations, Cloudflare écrit vouloir durcir l'ingestion de ses fichiers de configuration internes comme s'il s'agissait d'entrées utilisateur. La maille manquante : la même qu'au-dessus, seize mois plus tard, chez un autre géant.

Le 3 mars 2026, un déploiement bogué du cache des réglages utilisateur de GitHub fait expirer le cache de tout le monde en même temps. Recalcul massif, réécriture massive, la réplication prend du retard, et tout suit : au pic, environ 40 % des requêtes de github.com échouent, entre 18h46 et 20h09 UTC.

Le détail qui pique se lit dans leur rapport de disponibilité : la cause racine est la même qu'un incident survenu début février. La maille manquante : câbler chaque incident en garde-fou, faute de quoi il se rejoue.

Et puis Horizon, l'échelle au-dessus. Le logiciel de caisse des bureaux de poste britanniques, déployé à partir de 1999, produit des écarts comptables fictifs. La Post Office y voit des vols, et poursuit ses propres guichetiers.

Le premier volume du rapport d'enquête publique, publié le 8 juillet 2025, compte environ 1 000 personnes poursuivies et condamnées sur la foi de ces chiffres. Il n'écarte pas un lien causal avec au moins 13 suicides.

Pendant des années, des guichetiers ont signalé que le logiciel se trompait ; on les a traités en suspects plutôt qu'en rapporteurs de bug. Un filet ne sert à rien si les signalements du terrain finissent au tribunal.

Quatre contextes, un motif commun : à aucun moment le talent des équipes n'est en cause. Ce qui a manqué tient chaque fois en une protection systématique à un endroit précis : un validateur testé, une limite gérée, une leçon d'incident câblée, une oreille pour le terrain.

Six familles d'outils

La suite de la série suivra cette carte, mesurée sur un cas réel : ce blog, un projet Symfony tenu en solo. Tout ce qui suit s'exécute à chaque push, sans exception.

L'analyse statique lit le code sans l'exécuter et refuse ce qui peut casser : le type qui ne colle pas, le null oublié, la valeur d'erreur jamais testée. Ici, c'est PHPStan au niveau maximum, en bleeding edge, durci par des jeux de règles communautaires.

Et pour ce que l'analyse classique ne voit pas, un outil de niche surveille les fuites d'état du mode worker : Igor PHP a déjà son billet (premier scan : 269 signalements bruts, 3 vrais bugs).

Le style et le format ont l'air cosmétiques. Ils achètent surtout des diffs sans bruit : PHP-CS-Fixer, Twig-CS-Fixer, Biome et Stylelint tranchent les débats d'espaces une fois pour toutes. Une revue qui ne discute plus la forme discute le fond.

L'architecture se vérifie aussi. Deptrac interdit mécaniquement qu'un controller touche un repository, des tests d'architecture verrouillent les conventions du projet, et Rector propose la modernisation du code en continu. La règle n'est plus un vœu d'équipe, c'est un échec de build.

Les tests restent la famille la plus connue : unitaires, fonctionnels, navigateur, snapshots, mutation. Le billet sur les tests façon Cluedo leur donnait une méthode d'enquête ; la série y reviendra outil par outil, le runner en tête.

La sécurité et la chaîne d'approvisionnement ont leurs mailles dédiées : composer audit pour les CVE des dépendances, gitleaks pour la clé qui tente de se glisser dans un commit. Trivy bloque l'image Docker en CI dès qu'une vulnérabilité corrigeable s'y loge, et OWASP ZAP attaque l'application depuis l'extérieur.

Reste la mesure : complexité plafonnée, copier-coller détecté, code mort listé, couverture de types au-dessus de 99 %. Le tout produit des baselines qui n'ont le droit que de descendre. On y reviendra : c'est la partie la plus contre-intuitive, et la plus précieuse sur un projet qui a déjà une histoire.

Au-dessus de la carte, un orchestrateur fait tenir l'ensemble en une commande : Castor, déjà couvert, tout comme l'emballage Docker de ces outils. Sur le filet, chaque famille est une rangée de mailles : aucune ne rattrape tout, ensemble elles se recouvrent.

Comment tout ça s'assemble

Une liste d'outils ne protège rien tant qu'elle ne bloque rien. L'assemblage tient en trois moments. En local, un hook rejoue l'essentiel avant chaque push : le code part propre ou ne part pas. En CI, la suite complète conditionne la merge. Une fois par semaine, un audit long fait tourner ce qui serait trop lent au quotidien : complexité, dépendances inutilisées, code dupliqué, dépréciations.

La distinction qui compte est là : un contrôle qui échoue doit faire échouer quelque chose. Un gate informatif, c'est un filet posé par terre. Il documente la chute, il ne l'amortit pas.

Reste le problème de tout projet qui a vécu : la dette existante. Activer une analyse stricte sur des années de code remonte des centaines d'erreurs, et la tentation d'éteindre l'outil.

La réponse s'appelle ratchet, le cliquet : on fige l'existant dans une baseline, et le gate n'échoue que sur du nouveau. La dette d'hier est tolérée, celle de demain est refusée. C'est ce qui rend une QA exigeante vivable ailleurs que dans un projet de démo.

Ce mécanisme a un dernier mérite, très 2026 : les assistants de code font produire plus de lignes, plus vite, à des devs plus fatigués. « Une IA a trouvé les failles que ma QA ne voyait plus » l'a montré ici même : la relecture humaine, seule, ne tiendra pas la cadence. Le filet, lui, ne fatigue pas.

Le mot de la fin

Relisez les quatre pannes : aucune ne raconte une équipe médiocre. Elles racontent des chemins non gardés chez des gens brillants, et c'est exactement ce qui devrait inquiéter : si eux tombent là-dessus, personne n'a de raison de se croire à l'abri. La QA, au fond, c'est la forme outillée de l'humilité. On tisse le filet parce qu'on sait qu'on tombera.

La série commence par l'outil au meilleur rendement par ligne de configuration : PHPStan. Niveau maximum, bleeding edge, extensions, règles qui fâchent : le prochain billet montrera ce que ça attrape sur un projet en production, et ce que ça coûte à vivre.

D'ici là, une question à poser à votre propre projet : aujourd'hui, qu'est-ce qui empêche, concrètement, un unwrap() maison de partir en production un mardi matin ?

À quel point votre QA est-elle un vrai « gate » ?

Sur vos projets, quand une vérification de QA échoue (analyse statique, tests…), quelle est votre approche avant un déploiement ?

Une coquille, une erreur dans ce billet ? Signale-la-moi.

Ce billet est publié sous licence Creative Commons BY-NC-SA 4.0 (attribution, pas d'usage commercial, partage dans les mêmes conditions).

Vous aimerez aussi

Newsletter

Un mail quand il y a quelque chose à dire

Pas de tracking, pas de pub, pas de "10 astuces pour…". Juste les nouveaux billets et parfois une réflexion en plus.

Activez uniquement ce que vous souhaitez. Vos choix sont conservés 6 mois.

Strictement nécessaires

Indispensables au fonctionnement du site (session, sécurité, préférence d'affichage). Aucune donnée n'est partagée à des tiers et aucun consentement n'est requis.

Toujours actif

Mesure d'audience

Statistiques via Google Analytics (GA4) : pages vues, source du trafic, navigateur et interactions clés. Dépose des cookies de mesure, activés seulement avec votre accord (Consent Mode). Sans publicité ciblée, sans Google Signals, sans partage commercial.

Contenus externes

Affiche les GIF animés hébergés par Giphy (CDN aux États-Unis). À l'affichage d'un GIF, votre adresse IP et votre navigateur sont transmis à Giphy. Sans votre accord, les GIF ne s'affichent pas.