Cobertura de código com testes em Go: métricas, ferramentas e exemplos reais

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Cobertura de código com testes em Go: do "visto verde" à qualidade real

\n\n

No mundo do desenvolvimento Go, a frase "tenho 95% de cobertura" soa orgulhosa. Mas muitas vezes por trás desse número há um vazio: os testes verificam apenas o caminho feliz, enquanto casos limite e erros ficam de fora. Neste artigo, vamos entender como medir a cobertura de código com testes em Go de verdade, quais métricas são realmente importantes e quais ferramentas podem transformar os testes de uma formalidade em uma poderosa ferramenta de controle de qualidade.

\n\n

Não vamos apenas recontar a documentação. Em vez disso — exemplos reais, armadilhas e dicas práticas para quem programa em Go e quer dormir tranquilo.

\n\n

Por que simplesmente 80% é ruim?

\n\n

Suponha que você tenha uma função:

\n\n
func ProcessOrder(amount float64, discount bool) (float64, error) {\n    if amount <= 0 {\n        return 0, errors.New("amount must be positive")\n    }\n    if discount {\n        amount *= 0.9\n    }\n    return amount, nil\n}
\n\n

Você escreveu um teste: ProcessOrder(100, true) → 90, nil. Cobertura? 100% das linhas. Mas você não testou o caso com amount <= 0 e o caso sem desconto. Formalmente — cobertura excelente. Na prática — bugs garantidos. É por isso que as métricas de cobertura de código com testes em Go precisam ser analisadas em conjunto com outros indicadores.

\n\n

Ferramentas de cobertura: do simples ao complexo

\n\n

1. O nativo go test -cover

\n\n

A maneira mais simples de saber a cobertura de código com testes em Go é a flag -cover:

\n\n
go test -cover ./...
\n\n

Saída:

\n
ok      myproject/orders    0.234s    coverage: 72.3% of statements
\n\n

Mas isso é apenas um número geral. Para ver quais linhas não estão cobertas, use -coverprofile:

\n\n
go test -coverprofile=coverage.out ./...\ngo tool cover -html=coverage.out
\n\n

Um navegador será aberto com destaque: verde — coberto, vermelho — não. Este é o primeiro passo para entender as métricas de cobertura Go.

\n\n

2. go tool cover: modos e nuances

\n\n

go tool cover suporta três modos:

\n
    \n
  • set — se a linha foi executada pelo menos uma vez (padrão)
  • \n
  • count — quantas vezes cada linha foi executada
  • \n
  • atomic — count, mas com contadores atômicos para testes paralelos
  • \n
\n\n

Para análise de cobertura de testes Golang em código multithread, use atomic, caso contrário, você corre o risco de obter contadores incorretos devido a race conditions.

\n\n
go test -covermode=atomic -coverprofile=coverage.out ./...
\n\n

3. Race detector — cobertura oculta

\n\n

Condições de corrida (data races) são um dos principais problemas do código Go. Mesmo com 100% de cobertura de linhas, o race detector pode encontrar erros que os testes não perceberam. Execute os testes com a flag -race:

\n\n
go test -race -cover ./...
\n\n

Importante: o race detector torna os testes 2 a 20 vezes mais lentos, mas para módulos críticos, esta é uma prática obrigatória. Inclua-o no CI para pacotes-chave.

\n\n

Métricas que realmente importam

\n\n

A porcentagem de cobertura de linhas é apenas a ponta do iceberg. Aqui está o que você precisa monitorar:

\n\n

1. Cobertura de ramificações (branch coverage)

\n\n

O go test -cover padrão conta linhas, não ramos. Para cobertura de código com testes em Go no nível de ramificações, use gocov ou go-test-coverage. Exemplo:

\n\n
go get github.com/axw/gocov/gocov\ngocov test ./... | gocov report
\n\n

Você verá não apenas as linhas, mas também a quantidade de condições não cobertas. Por exemplo, para uma função com dois ifs — 4 ramos, dos quais 2 estão cobertos.

\n\n

2. Cobertura por mutação (mutation testing)

\n\n

A maneira mais honesta de avaliar a qualidade dos testes é

Blogs

Book Recommendations