Introdução: A eterna pergunta "Como exibir algo em um teste?"
\n\nVocê está escrevendo um teste em Go. A lógica é complexa, os dados são confusos e você precisa vitalmente ver o que está acontecendo internamente. Automaticamente você escreve fmt.Println("value =", x), executa o teste... e vê silêncio. Nenhuma saída. Familiar?
Esta pergunta é uma das mais populares no Stack Overflow entre desenvolvedores Go iniciantes (e não só!). Parece que o que poderia ser mais simples do que exibir uma string? Mas no mundo dos testes Go existem regras próprias e um conjunto de ferramentas adequadas. Neste artigo, vamos analisar todas as formas de saída em testes, organizar as melhores práticas de 2025 e mostrar como não cometer erros. Vamos lá!
\n\nPor que fmt.Println fica em silêncio? (E quando ele finalmente fala)
\n\nVamos direto ao ponto. Quando você executa testes com o comando go test (sem flags), a saída padrão (stdout) é suprimida. O executor de testes Go considera que, se o teste passou com sucesso, o usuário não precisa ver toneladas de informações de depuração. Isso é feito para limpeza e automação — imagine se cada teste exibisse 10 linhas de log a cada execução de CI/CD.
No entanto, existem duas exceções em que fmt.Println ainda aparecerá na tela:
- \n
- Flag
-v(verbose):go test -v. Este modo ativa a saída detalhada de todos os testes. Você verá mensagens defmt.Printlne outras funções. \n - Teste falhou: Se o teste terminou com erro (chamou
t.Errorout.Fatal), a saída defmt.Printlndeste teste será exibida. Isso é muito útil para depuração. \n
Mas confiar em fmt.Println é falta de educação. Para testes em Go, existe uma ferramenta especial, mais correta e poderosa.
O rei da festa: t.Log() e t.Logf()
\n\nO objeto testing.T (que é passado para cada teste) possui métodos embutidos para registro de log. Memorize-os como o "Pai Nosso": t.Log() e t.Logf().
package main\n\nimport (\n "testing"\n)\n\nfunc TestSum(t *testing.T) {\n result := 2 + 2\n // Log simples\n t.Log("Iniciando teste de soma")\n t.Log("Resultado do cálculo:", result)\n\n // Log com formatação (como fmt.Printf)\n t.Logf("A soma de 2 e 2 é %d. Verificação passou!", result)\n\n if result != 4 {\n t.Errorf("Esperava 4, obtive %d", result)\n }\n}\n\nExecute este teste com a flag -v:
go test -v -run TestSum\n\nE você verá mensagens bonitas e estruturadas diretamente na saída do teste.
\n\nPor que t.Log é melhor que fmt.Println?
\n- \n
- Contexto: As mensagens de
t.Logsão automaticamente vinculadas ao teste específico. Na saída-v, você vê qual teste imprimiu o quê. \n - Controlabilidade: A saída de
t.Logé exibida apenas com-vou quando o teste falha. Isso significa que seus logs não poluem o console durante a execução normal. \n - Segurança: Ao contrário de
fmt.Fprintf(os.Stderr, ...),t.Logfunciona corretamente com testes paralelos (t.Parallel) e não causa race condition. \n
O lado negro da força: t.Error() e t.Fatal() como ferramenta de saída
\n\nMuitos iniciantes usam t.Error() apenas para parar o teste em caso de erro. Mas na verdade esta é uma ótima (e correta!) maneira de exibir informações diagnósticas importantes, especialmente quando o teste falha.
O segredo é que a mensagem passada para t.Error() ou t.Fatal() sempre será exibida, mesmo sem a flag -v. Isso os torna ideais para exibir informações críticas