Il existe une situation que toute équipe qui exploite un logiciel finit par rencontrer : la suite de tests est au vert, la couverture est bonne, la livraison se passe sans erreur, et le service est inutilisable.
Ce n'est pas un paradoxe. C'est la conséquence directe de ce que les tests unitaires mesurent, et de ce qu'ils ne mesurent pas.
Nous exploitons NeuraScope en production et nous la déployons chez nos clients. Voici la famille de pannes qui échappe structurellement aux tests, et le dispositif qui la rattrape.
Ce qu'un test unitaire vérifie réellement
Un test unitaire s'exécute dans un environnement fabriqué pour lui. La base de données est créée à la volée, souvent en mémoire. Les services externes sont remplacés par des doublures. La configuration est celle du mode test. Les fichiers sont écrits dans un dossier temporaire.
Cet isolement est une qualité : il rend les tests rapides, reproductibles, et indépendants de l'état du monde. C'est aussi précisément ce qui les aveugle.
Un test unitaire vérifie qu'une fonction, placée dans les conditions qu'on a définies, produit le résultat attendu. Il ne vérifie jamais que ces conditions existent en production.
La distinction paraît théorique. Elle ne l'est pas : elle décrit exactement l'endroit où les pannes de mise en production se produisent.
La famille des pannes d'assemblage
Ces pannes ont une signature commune. Chaque composant fonctionne correctement, et l'ensemble ne fonctionne pas, parce que quelque chose qui n'appartient à aucun composant a changé.
Le cache de configuration. Une application optimisée pour la production fige sa configuration dans un fichier compilé. Si le déploiement modifie un paramètre sans régénérer ce cache, l'application continue de tourner avec l'ancienne valeur. Aucun test ne le voit, parce que les tests ne passent jamais par ce cache.
Les droits sur le système de fichiers. Le serveur web s'exécute sous un compte donné. Après un déploiement qui rétablit les propriétaires, ce compte peut perdre l'accès à un dossier de journaux ou de cache. L'application démarre, puis échoue à la première écriture. Le test, lui, écrivait dans un dossier temporaire dont il était propriétaire.
Les liens symboliques. Les fichiers téléversés sont souvent exposés au public par un lien symbolique. Si ce lien pointe vers un chemin qui n'existe plus après une réorganisation, toutes les images disparaissent. Le code n'a pas changé, les tests ne changent pas de comportement, et le site affiche des cadres vides.
Les dépendances absentes. Une bibliothèque installée en développement, oubliée sur le serveur. Le code qui l'utilise échoue à l'exécution, dans un chemin peu fréquenté qui ne se manifeste que plusieurs jours après.
Les fichiers compilés non régénérés. Le style et le script d'une interface sont construits à partir de sources. Si cette construction n'est pas relancée au déploiement, la page charge des fichiers qui ne correspondent plus au code : classes absentes, comportements manquants. La page s'affiche, mal.
La configuration du serveur web. Une directive commentée, une règle de réécriture modifiée, un certificat expiré. L'application n'est pas en cause, et pourtant rien ne répond.
Ces six situations ont en commun de vivre dans l'espace entre le code et son exécution. Aucune suite de tests, aussi complète soit-elle, n'y a accès.
Le coût réel de ces pannes
Ce qui rend ces pannes coûteuses n'est pas leur difficulté de correction. La plupart se réparent en quelques minutes, parfois en une seule commande.
Ce qui coûte, c'est le délai de détection.
Une régression fonctionnelle subtile est souvent découverte par un utilisateur attentif qui la signale. Une page blanche, elle, est découverte par le premier visiteur venu, qui repart sans rien dire. Entre le déploiement et le signalement, le service est indisponible pour tout le monde.
Sur un site public, ce délai se mesure en visiteurs perdus. Sur une plateforme utilisée en interne, il se mesure en appels au support et en confiance entamée. Dans les deux cas, le préjudice est disproportionné par rapport à la trivialité de la cause.
Une plateforme d'IA ajoute une variante spécifique à cette famille : la panne partiellement silencieuse. L'interface répond, les questions aboutissent, mais un connecteur a cessé d'alimenter la base. Le système continue de fonctionner sur des données figées. Personne ne voit d'erreur, et les réponses deviennent progressivement obsolètes.
Le smoke test : vérifier que ça démarre
Le terme vient d'une pratique électronique : on branche l'appareil, et on regarde s'il fume. Ce n'est pas un test de qualité, c'est un test d'existence.
Appliqué à un logiciel, le principe est de vérifier après chaque mise en production qu'une poignée de chemins essentiels répondent. Pas qu'ils répondent bien : qu'ils répondent.
Sur une plateforme comme NeuraScope, le noyau tient en quelques vérifications.
L'infrastructure répond. La base de données accepte une connexion. La file d'attente est joignable. Les dossiers de journaux sont accessibles en écriture. Ce sont les trois dépendances dont l'absence rend tout le reste inutile, et elles se vérifient en quelques millisecondes.
Les points d'entrée répondent. La page d'accueil, la page de connexion, les principaux points d'accès de l'interface. Ce qu'on cherche ici est le code de réponse, pas le contenu. Une erreur serveur ou une redirection inattendue sont des signaux suffisants.
L'authentification fonctionne. Un utilisateur peut-il obtenir une session ? Une ressource protégée refuse-t-elle un accès non authentifié ? Cette seconde vérification est aussi importante que la première : une panne de contrôle d'accès est plus grave qu'une panne d'accès.
Le cœur fonctionnel répond. Sur une plateforme documentaire, cela signifie qu'une question posée sur un corpus connu renvoie une réponse structurée. On ne juge pas la pertinence, on vérifie que la chaîne complète est traversée : recherche, récupération, génération.
Les fichiers statiques sont servis. Les images, les feuilles de style, les scripts. C'est la vérification qui attrape les liens symboliques cassés et les fichiers non reconstruits.
L'ensemble s'exécute en quelques dizaines de secondes. C'est le rapport le plus favorable entre le coût d'un dispositif et le préjudice qu'il évite.
Ce qui distingue un bon smoke test
Trois propriétés le rendent utile, et leur absence le rend nuisible.
Il doit être rapide. Un dispositif qui prend dix minutes ne sera pas exécuté à chaque déploiement. Il finira désactivé pour gagner du temps, précisément le jour où il aurait servi.
Il ne doit jamais échouer sans raison. Un test instable, qui passe une fois sur deux, détruit la valeur de l'ensemble : l'équipe prend l'habitude de relancer, puis d'ignorer. Un smoke test qui échoue doit signifier que quelque chose est réellement cassé, sans exception.
Il doit être exécuté au bon moment. Après le déploiement, sur l'environnement réel. Un test exécuté avant la mise en production ne voit rien de ce qui se passe pendant celle-ci, et c'est justement là que naissent ces pannes.
Un quatrième point, moins évident : il doit vérifier des chemins que personne ne regarde. Les pages consultées en permanence signalent leur panne d'elles-mêmes. Ce sont les parcours rares qui restent cassés longtemps : la réinitialisation de mot de passe, l'export d'un rapport, la page d'erreur personnalisée.
Où s'arrête un smoke test
Il faut être clair sur ce qu'il ne fait pas, sinon il donne une fausse assurance.
Il ne mesure aucune qualité. Un smoke test qui valide une réponse d'IA vérifie qu'une réponse arrive, pas qu'elle soit juste. Confondre les deux revient à annoncer une garantie qui n'existe pas.
Il ne remplace pas la surveillance continue. Il constate l'état à un instant donné, celui du déploiement. Une panne survenue trois heures plus tard demande un dispositif qui tourne en permanence.
Il ne couvre pas les pannes progressives. Une base qui sature lentement, une latence qui dérive, un corpus qui vieillit : rien de tout cela ne produit d'échec franc. Ces situations relèvent de la surveillance dans la durée, avec un historique et des seuils.
C'est la raison pour laquelle nous distinguons deux dispositifs. Le smoke test répond à la question « est-ce que ça marche maintenant ? » après chaque changement. La surveillance synthétique répond à « est-ce que ça marche toujours ? », en continu, avec des mesures suivies dans le temps et des seuils qui déclenchent une alerte.
Les deux sont nécessaires, et aucun ne remplace l'autre.
Une méthode simple pour construire le vôtre
Si vous n'avez aucun dispositif, la manière la plus rapide de commencer ne consiste pas à concevoir une architecture de test.
Elle consiste à répondre à une question : que faites-vous manuellement après chaque mise en production pour vérifier que tout va bien ?
Presque toutes les équipes ont ce rituel, même informel. On ouvre la page d'accueil, on se connecte, on regarde si l'écran principal s'affiche. Ces trois gestes sont déjà un smoke test. Il suffit de les écrire sous forme de vérifications automatiques.
Ensuite, chaque fois qu'une panne de production survient, la question à poser est : quelle vérification l'aurait détectée en une minute ? La réponse rejoint le dispositif. C'est ainsi qu'il grossit, guidé par les incidents réels plutôt que par l'imagination.
Cette méthode a un avantage sur toute liste théorique : elle produit un dispositif qui correspond à vos pannes, pas à celles des autres.
Ce qu'il faut retenir
Une suite de tests au vert prouve que le code se comporte comme prévu dans les conditions prévues. Elle ne prouve rien sur l'existence de ces conditions en production.
Entre les deux se loge une famille de pannes triviales à corriger et coûteuses à subir : configuration figée, droits perdus, liens cassés, fichiers non reconstruits. Elles ne demandent pas un dispositif sophistiqué, mais un dispositif systématique.
Trois minutes de vérifications après chaque mise en production, ou un appel client. C'est le seul arbitrage réel.