Por que o Go esconde os resultados dos testes? (E como isso atrapalha a vida)
\n\nImagine: você programa em Go, executa go test, vê a marca verde... mas algo deu errado. Você corrigiu um bug, executa os testes novamente — e vê verde de novo. E o bug continua lá! Familiar? Bem-vindo ao mundo do cache de testes do Go.
Go é uma linguagem que adora velocidade. Para não executar os mesmos testes várias vezes, o compilador armazena os resultados em cache. Parece conveniente, até você se deparar com uma situação em que o cache de testes do Go começa a trabalhar contra você. Isso afeta especialmente desenvolvedores que trabalham com testes de integração, sistema de arquivos ou APIs externas.
\n\nNeste artigo, analisaremos duas abordagens para resolver o problema: force retesting (reinicialização forçada) e a desativação completa do cache de testes. Você aprenderá quando usar cada uma e terá exemplos de código funcionais.
\n\nComo funciona o cache de testes em Go
\n\nAntes de quebrar, vamos entender como funciona. O Go armazena em cache os resultados dos testes com base em um hash de:
\n- \n
- Código-fonte (arquivos
.go) \n - Arquivos de teste \n
- Variáveis de ambiente \n
- Flags de compilação \n
Se nada mudou — o Go simplesmente mostra o resultado em cache. Rápido? Sim. Perigoso? Com certeza! Imagine que seu teste depende de tempo, números aleatórios ou um serviço externo. O cache dirá: "Está tudo ok!", embora na verdade o teste já teria falhado há muito tempo.
\n\n// Exemplo de teste que ficará falso-verde devido ao cache\nfunc TestCurrentTime(t *testing.T) {\n now := time.Now()\n if now.Year() != 2024 {\n t.Errorf("O ano deve ser 2024, obtido %d", now.Year())\n }\n}\n\nExecute este teste uma vez — ele passará. Corrigiu o ano para 2025 no código? O cache ainda mostrará o resultado antigo. E você ficará se perguntando por que o CI falha, enquanto localmente tudo "funciona".
\n\nAbordagem 1: Force retesting (reinicialização forçada)
\n\nA forma mais popular de combater o cache é a flag -count=1. Isso é o force retesting em sua forma pura. Ele diz ao Go: "Não confie no cache, execute o teste novamente".
// Execução com reinicialização forçada\ngo test -count=1 ./...\n\nPor que -count=1 e não -count=0? Porque -count define o número de execuções do teste. 1 é o valor mínimo que desativa o cache. 0 simplesmente não executará nada.
Quando usar force retesting
\n- \n
- Testes de integração que acessam banco de dados ou API \n
- Testes com dados aleatórios (testes fuzz, geração de UUID) \n
- Testes dependentes de tempo (timeouts, datas) \n
- Desenvolvimento local, quando você altera o código com frequência \n
Exemplo: teste de integração com force retesting
\n\npackage db_test\n\nimport (\n "testing"\n "time"\n)\n\nfunc TestDatabaseConnection(t *testing.T) {\n // Este teste depende de um servidor ativo\n // Sem -count=1 ele pode mostrar um resultado antigo\n db := connectToDatabase()\n if err := db.Ping(); err != nil {\n t.Fatalf("Não foi possível conectar: %v", err)\n }\n \n // Simulação de atraso temporário\n time.Sleep(100 * time.Millisecond)\n if err := db.Query("SELECT 1"); err != nil {\n t.Errorf("Consulta não executada: %v", err)\n }\n}\n\nExecute: go test -count=1 -v ./db/. Agora cada execução é honesta. Mas há um detalhe: o force retesting não resolve o problema globalmente. Se você esquecer a flag — o cache voltará.
Abordagem 2: Desativação completa do cache de testes
\n\nA segunda opção é radical. Você simplesmente diz ao Go: "Não armazene nada em cache". Isso é feito através da variável de ambiente GOCACHE=off ou da flag -count=1