---
title: "Testes em Go: Guia Completo de Testing"
url: "https://golang.com.br/aprenda/testes-go/"
markdown_url: "https://golang.com.br/aprenda/testes-go.MD"
description: "Aprenda a testar em Go: go test, table-driven tests, benchmarks, mocks com testify e cobertura de 80%+. Com exemplos prontos pra copiar e rodar."
date: "2026-01-29"
author: ""
---

# Testes em Go: Guia Completo de Testing

Aprenda a testar em Go: go test, table-driven tests, benchmarks, mocks com testify e cobertura de 80%+. Com exemplos prontos pra copiar e rodar.


# Testes em Go: Guia Completo

Go tem testing integrado na linguagem. Sem frameworks externos, sem configuração complicada.

## Básico

Crie um arquivo `*_test.go`:

```go
// math.go
package math

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

```go
// math_test.go
package math

import "testing"

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

Execute:
```bash
go test
```

## Table-Driven Tests

O padrão mais usado em Go:

```go
func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positivos", 2, 3, 5},
        {"negativos", -1, -1, -2},
        {"zero", 0, 0, 0},
        {"misto", -1, 5, 4},
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            result := Add(tt.a, tt.b)
            if result != tt.expected {
                t.Errorf("Add(%d, %d) = %d; want %d",
                    tt.a, tt.b, result, tt.expected)
            }
        })
    }
}
```

Saída:
```
=== RUN   TestAdd
=== RUN   TestAdd/positivos
=== RUN   TestAdd/negativos
=== RUN   TestAdd/zero
=== RUN   TestAdd/misto
--- PASS: TestAdd (0.00s)
```

## Subtests e t.Run

```go
func TestUser(t *testing.T) {
    t.Run("Create", func(t *testing.T) {
        // teste de criação
    })
    
    t.Run("Update", func(t *testing.T) {
        // teste de atualização
    })
    
    t.Run("Delete", func(t *testing.T) {
        // teste de deleção
    })
}
```

Execute teste específico:
```bash
go test -run TestUser/Create
```

## Setup e Teardown

### Por teste

```go
func TestDatabase(t *testing.T) {
    // Setup
    db := setupTestDB()
    defer db.Close()
    
    // Teste
    // ...
}
```

### Global (TestMain)

```go
func TestMain(m *testing.M) {
    // Setup global
    db := setupTestDB()
    
    // Rodar todos os testes
    code := m.Run()
    
    // Teardown global
    db.Close()
    
    os.Exit(code)
}
```

## Benchmarks

```go
func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}
```

Execute:
```bash
go test -bench=.
```

Saída:
```
BenchmarkAdd-8    1000000000    0.29 ns/op
```

### Benchmark com setup

```go
func BenchmarkSort(b *testing.B) {
    data := generateData(10000)
    
    b.ResetTimer() // Não conta o setup
    
    for i := 0; i < b.N; i++ {
        sort.Ints(data)
    }
}
```

## Coverage

```bash
# Ver coverage
go test -cover

# Gerar HTML
go test -coverprofile=coverage.out
go tool cover -html=coverage.out
```

## Mocking

### Interface-based

```go
// Interface
type UserRepository interface {
    GetByID(id int) (*User, error)
}

// Mock
type MockUserRepo struct {
    users map[int]*User
}

func (m *MockUserRepo) GetByID(id int) (*User, error) {
    if user, ok := m.users[id]; ok {
        return user, nil
    }
    return nil, errors.New("not found")
}

// Teste
func TestUserService(t *testing.T) {
    mock := &MockUserRepo{
        users: map[int]*User{
            1: {ID: 1, Name: "Alice"},
        },
    }
    
    service := NewUserService(mock)
    user, err := service.GetUser(1)
    
    if err != nil {
        t.Fatal(err)
    }
    if user.Name != "Alice" {
        t.Errorf("expected Alice, got %s", user.Name)
    }
}
```

### Com testify/mock

```bash
go get github.com/stretchr/testify
```

```go
type MockRepo struct {
    mock.Mock
}

func (m *MockRepo) GetByID(id int) (*User, error) {
    args := m.Called(id)
    return args.Get(0).(*User), args.Error(1)
}

func TestWithTestify(t *testing.T) {
    mockRepo := new(MockRepo)
    mockRepo.On("GetByID", 1).Return(&User{Name: "Alice"}, nil)
    
    service := NewService(mockRepo)
    user, _ := service.GetUser(1)
    
    assert.Equal(t, "Alice", user.Name)
    mockRepo.AssertExpectations(t)
}
```

## HTTP Testing

```go
func TestHandler(t *testing.T) {
    // Criar request
    req := httptest.NewRequest("GET", "/users/1", nil)
    rec := httptest.NewRecorder()
    
    // Chamar handler
    handler := http.HandlerFunc(GetUserHandler)
    handler.ServeHTTP(rec, req)
    
    // Verificar
    if rec.Code != http.StatusOK {
        t.Errorf("status = %d; want %d", rec.Code, http.StatusOK)
    }
    
    var user User
    json.NewDecoder(rec.Body).Decode(&user)
    if user.ID != 1 {
        t.Errorf("user.ID = %d; want 1", user.ID)
    }
}
```

### Servidor de teste

```go
func TestAPI(t *testing.T) {
    srv := httptest.NewServer(http.HandlerFunc(myHandler))
    defer srv.Close()
    
    resp, err := http.Get(srv.URL + "/endpoint")
    // ...
}
```

## Testes Paralelos

```go
func TestParallel(t *testing.T) {
    t.Parallel() // Marca como paralelo
    
    // teste...
}
```

```bash
go test -parallel 4
```

## Comandos Úteis

```bash
# Rodar todos os testes
go test ./...

# Verbose
go test -v

# Teste específico
go test -run TestAdd

# Com race detection
go test -race

# Timeout
go test -timeout 30s

# Cache off
go test -count=1
```

## Estrutura de Projeto

```
project/
├── user.go
├── user_test.go
├── user_integration_test.go
└── testdata/
    └── fixtures.json
```

## Build Tags

```go
//go:build integration

package mypackage

func TestIntegration(t *testing.T) {
    // Só roda com: go test -tags=integration
}
```

## Boas Práticas

1. **Nome descritivo** — `TestUserCreate_WithInvalidEmail_ReturnsError`
2. **Table-driven** — Para múltiplos cenários
3. **Isolamento** — Cada teste independente
4. **Fast** — Testes unitários < 1s
5. **Determinístico** — Mesmo resultado sempre
6. **Coverage > 70%** — Meta razoável

## Exemplo Completo

```go
// user_service_test.go
package user

import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestUserService_Create(t *testing.T) {
    tests := []struct {
        name    string
        input   CreateUserInput
        wantErr bool
    }{
        {
            name:    "valid user",
            input:   CreateUserInput{Name: "Alice", Email: "alice@test.com"},
            wantErr: false,
        },
        {
            name:    "empty name",
            input:   CreateUserInput{Name: "", Email: "test@test.com"},
            wantErr: true,
        },
        {
            name:    "invalid email",
            input:   CreateUserInput{Name: "Bob", Email: "invalid"},
            wantErr: true,
        },
    }
    
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            service := NewUserService(NewMockRepo())
            
            user, err := service.Create(tt.input)
            
            if tt.wantErr {
                require.Error(t, err)
                return
            }
            
            require.NoError(t, err)
            assert.NotZero(t, user.ID)
            assert.Equal(t, tt.input.Name, user.Name)
        })
    }
}
```

---

## Veja Também

- [API REST com Go](/aprenda/api-rest-go/)
- [Go para Iniciantes](/aprenda/go-para-iniciantes/)
- [Vagas Go](/vagas/)

---

*Última atualização: Janeiro 2026*

Quer comparar frameworks de teste? Veja como <a href="https://rustlang.com.br/blog/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'rustlang.com.br' })">Rust</a> integra testes ao compilador com `#[test]` e `cargo test`, e como <a href="https://python.dev.br/blog/" target="_blank" rel="noopener noreferrer" onclick="umami.track('portfolio-site-click', { destination: 'python.dev.br' })">Python</a> usa pytest com fixtures e parametrização.

---

## Veja também

- [API REST com Go](/aprenda/api-rest-go/) — Aplique testes numa API real
- [Concorrência em Go](/aprenda/concorrencia-go/) — Teste código concorrente
- [Interfaces em Go](/aprenda/golang-interfaces/) — Use interfaces para mocks
- [Go Cheatsheet](/cheatsheet/) — Referência rápida de sintaxe
