Cache en Go : ennemi des tests ? Décortiquons le force retesting

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi Go cache-t-il les résultats des tests ? (Et comment ça gâche la vie)

\n\n

Imaginez : vous codez en Go, vous lancez go test, vous voyez un coche vert... mais quelque chose cloche. Vous avez corrigé un bug, vous relancez les tests — et à nouveau le feu vert. Pourtant, le bug est toujours là ! Ça vous dit quelque chose ? Bienvenue dans le monde de la mise en cache des tests Go.

\n\n

Go est un langage qui aime la vitesse. Pour ne pas relancer les mêmes tests dix fois, le compilateur met en cache les résultats. Ça semble pratique, jusqu'à ce que vous soyez confronté à une situation où le cache des tests Go commence à jouer contre vous. Cela frappe particulièrement les développeurs qui travaillent avec des tests d'intégration, le système de fichiers ou des API externes.

\n\n

Dans cet article, nous allons décortiquer deux approches pour résoudre le problème : le force retesting (redémarrage forcé) et la désactivation complète du cache des tests. Vous apprendrez quand utiliser quoi, et vous obtiendrez des exemples de code fonctionnels.

\n\n

Comment fonctionne la mise en cache des tests en Go

\n\n

Avant de casser, comprenons comment ça marche. Go met en cache les résultats des tests sur la base d'un hachage de :

\n
    \n
  • Le code source (fichiers .go)
  • \n
  • Les fichiers de test
  • \n
  • Les variables d'environnement
  • \n
  • Les flags de compilation
  • \n
\n\n

Si rien n'a changé — Go affiche simplement le résultat mis en cache. Rapide ? Oui. Dangereux ? Et comment ! Imaginez que votre test dépende de l'heure, de nombres aléatoires ou d'un service externe. Le cache dira : « Tout va bien ! », alors qu'en réalité le test aurait échoué depuis longtemps.

\n\n
// Exemple de test qui sera faussement vert à cause du cache\nfunc TestCurrentTime(t *testing.T) {\n    now := time.Now()\n    if now.Year() != 2024 {\n        t.Errorf("L'année devrait être 2024, obtenu %d", now.Year())\n    }\n}
\n\n

Lancez ce test une fois — il passera. Vous corrigez l'année en 2025 dans le code ? Le cache affichera quand même l'ancien résultat. Et vous vous demanderez pourquoi la CI échoue, alors qu'en local tout « marche ».

\n\n

Approche 1 : Force retesting (redémarrage forcé)

\n\n

La méthode la plus populaire pour lutter contre le cache est le flag -count=1. C'est le force retesting dans sa forme la plus pure. Il dit à Go : « Ne fais pas confiance au cache, relance le test à nouveau ».

\n\n
// Lancement avec redémarrage forcé\ngo test -count=1 ./...
\n\n

Pourquoi -count=1 et pas -count=0 ? Parce que -count définit le nombre d'exécutions du test. 1 est la valeur minimale qui désactive le cache. 0 ne lancera tout simplement rien.

\n\n

Quand utiliser le force retesting

\n
    \n
  • Tests d'intégration qui accèdent à une base de données ou une API
  • \n
  • Tests avec données aléatoires (fuzz tests, génération d'UUID)
  • \n
  • Tests dépendant du temps (timeouts, dates)
  • \n
  • Développement local, lorsque vous modifiez fréquemment le code
  • \n
\n\n

Exemple : test d'intégration avec force retesting

\n\n
package db_test\n\nimport (\n    "testing"\n    "time"\n)\n\nfunc TestDatabaseConnection(t *testing.T) {\n    // Ce test dépend d'un serveur en direct\n    // Sans -count=1, il pourrait afficher un résultat obsolète\n    db := connectToDatabase()\n    if err := db.Ping(); err != nil {\n        t.Fatalf("Impossible de se connecter : %v", err)\n    }\n    \n    // Simulation d'un délai temporel\n    time.Sleep(100 * time.Millisecond)\n    if err := db.Query("SELECT 1"); err != nil {\n        t.Errorf("Requête échouée : %v", err)\n    }\n}
\n\n

On lance : go test -count=1 -v ./db/. Maintenant, chaque exécution est honnête. Mais il y a un bémol : le force retesting ne résout pas le problème globalement. Si vous oubliez le flag, le cache reviendra.

\n\n

Approche 2 : Désactivation complète du cache des tests

\n\n

La deuxième option est radicale. Vous dites simplement à Go : « Ne mets rien en cache ». Cela se fait via la variable d'environnement GOCACHE=off ou le flag -count=1

Blogs

Book Recommendations