Why Does Go Hide Test Results? (And How It Breaks Your Workflow)
\n\nImagine: you're writing Go, you run go test, you see a green checkmark... but something went wrong. You fixed a bug, run the tests again—and you get a green light again. But the bug is still there! Sound familiar? Welcome to the world of Go test caching.
Go is a language that loves speed. To avoid running the same tests ten times over, the compiler caches results. This sounds convenient until you encounter a situation where the Go test cache starts working against you. This is especially painful for developers working with integration tests, the file system, or external APIs.
\n\nIn this article, we'll break down two approaches to solving the problem: force retesting and completely disabling the test cache. You'll learn when to use which approach and get working code examples.
\n\nHow Test Caching Works in Go
\n\nBefore we break things, let's understand how it works. Go caches test results based on a hash of:
\n- \n
- Source code (
.gofiles) \n - Test files \n
- Environment variables \n
- Compilation flags \n
If nothing has changed—Go simply shows the cached result. Fast? Yes. Dangerous? Absolutely! Imagine your test depends on time, random numbers, or an external service. The cache will say, "All good!" even though the test would have failed long ago.
\n\n// Example of a test that will be falsely green due to the cache\nfunc TestCurrentTime(t *testing.T) {\n now := time.Now()\n if now.Year() != 2024 {\n t.Errorf("Year should be 2024, got %d", now.Year())\n }\n}\n\nRun this test once—it passes. Change the year to 2025 in the code? The cache will still show the old result. And you'll be left wondering why CI is failing while everything "works" locally.
\n\nApproach 1: Force Retesting
\n\nThe most popular way to fight the cache is the -count=1 flag. This is force retesting in its pure form. It tells Go: "Don't trust the cache, run the test again from scratch."
// Run with force retesting\ngo test -count=1 ./...\n\nWhy -count=1 and not -count=0? Because -count specifies the number of times to run the test. 1 is the minimum value that disables the cache. 0 simply won't run anything.
When to Use Force Retesting
\n- \n
- Integration tests that access a database or API \n
- Tests with random data (fuzz tests, UUID generation) \n
- Tests that depend on time (timeouts, dates) \n
- Local development when you frequently change code \n
Example: Integration Test with Force Retesting
\n\npackage db_test\n\nimport (\n "testing"\n "time"\n)\n\nfunc TestDatabaseConnection(t *testing.T) {\n // This test depends on a live server\n // Without -count=1 it might show an old result\n db := connectToDatabase()\n if err := db.Ping(); err != nil {\n t.Fatalf("Failed to connect: %v", err)\n }\n \n // Simulate a time delay\n time.Sleep(100 * time.Millisecond)\n if err := db.Query("SELECT 1"); err != nil {\n t.Errorf("Query failed: %v", err)\n }\n}\n\nRun it: go test -count=1 -v ./db/. Now every run is honest. But there's a catch: force retesting doesn't solve the problem globally. If you forget the flag—the cache comes back.
Approach 2: Completely Disabling the Test Cache
\n\nThe second option is radical. You simply tell Go: "Don't cache anything." This is done via the environment variable GOCACHE=off or the flag -count=1.