Testes em Go: unit, integration, e2e — guia completo

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

Introdução: Por que testar em Go é fundamental



Go (Golang) foi criado com foco em simplicidade e confiabilidade. O pacote embutido testing é uma das melhores ferramentas para escrever testes entre as linguagens modernas. Ele não requer bibliotecas de terceiros para cenários básicos, mas é facilmente extensível. Neste artigo, vamos abordar três níveis de teste: unit, integration e e2e. Você aprenderá como escrevê-los, quando aplicá-los e quais ferramentas usar. O material será útil tanto para iniciantes quanto para desenvolvedores Go experientes.



1. Testes unitários em Go: o básico dos básicos



Testes unitários verificam funções ou métodos individuais isoladamente. Em Go, basta criar um arquivo com o sufixo _test.go e escrever funções no formato TestXxx(t *testing.T).



Exemplo simples de teste unitário



Suponha que temos uma função de soma:



// math.gopackage main

func Add(a, b int) int { return a + b}


O teste para ela:



// math_test.gopackage main

import "testing"

func TestAdd(t *testing.T) { result := Add(2, 3) expected := 5 if result != expected { t.Errorf("Add(2, 3) = %d; want %d", result, expected) }}


Testes orientados a tabela (Table-Driven Tests)



A comunidade Go recomenda usar testes orientados a tabela para verificar múltiplos casos:



func TestAddTable(t *testing.T) {    tests := []struct {        name string        a, b int        want int    }{        {"positive", 2, 3, 5},        {"negative", -1, -2, -3},        {"zero", 0, 0, 0},    }    for _, tt := range tests {        t.Run(tt.name, func(t *testing.T) {            if got := Add(tt.a, tt.b); got != tt.want {                t.Errorf("Add() = %d, want %d", got, tt.want)            }        })    }}


Os testes unitários são executados com o comando:



go test ./...


2. Testes de integração: verificando a interação



Testes de integração verificam como diferentes partes do sistema funcionam juntas: banco de dados, API, sistema de arquivos. Em Go, é comum colocá-los em arquivos separados com uma tag de compilação ou no pacote integration.



Usando build tags



Crie um arquivo integration_test.go com a tag:



//go:build integration

package integration

import ( "database/sql" "testing" _ "github.com/lib/pq")

func TestDatabaseConnection(t *testing.T) { dsn := "host=localhost port=5432 user=test dbname=test sslmode=disable" db, err := sql.Open("postgres", dsn) if err != nil { t.Fatalf("Failed to open DB: %v", err) } defer db.Close()

err = db.Ping() if err != nil { t.Fatalf("Failed to ping DB: %v", err) }}


Executando apenas os testes de integração:



go test -tags=integration ./...


Trabalhando com banco de dados de teste



Para testes de integração, frequentemente se usa testcontainers-go ou bancos de dados in-memory (ex.: SQLite). Exemplo com testcontainers:



func TestWithPostgresContainer(t *testing.T) {    ctx := context.Background()    pgContainer, err := postgres.RunContainer(ctx,        testcontainers.WithImage("postgres:15"),        postgres.WithDatabase("testdb"),    )    require.NoError(t, err)    defer pgContainer.Terminate(ctx)

dsn, _ := pgContainer.ConnectionString(ctx) // usamos dsn para conectar}


3. Testes E2E: verificando o sistema como um todo



Testes End-to-End simulam o comportamento do usuário e verificam todo o sistema do início ao fim. Em Go, eles são frequentemente escritos para serviços HTTP usando o pacote net/http/httptest.



Exemplo de teste E2E para REST API



func TestCreateUserE2E(t *testing.T) {    // C                

Blogs

Book Recommendations