Communitygithub.com

golang-testing

Padrões de teste em Go incluindo testes orientados por tabela, subtestes, benchmarks, fuzzing e cobertura de teste. Segue a metodologia TDD com práticas idiomáticas de Go. Use ao escrever testes em Go — casos orientados por tabela, subtestes, benchmarks, fuzzing ou cobertura.

O que é golang-testing?

Este skill fornece um guia abrangente sobre padrões de teste em Go, essencial para desenvolvedores que desejam escrever testes confiáveis e de fácil manutenção seguindo a metodologia TDD (Test-Driven Development). Ele é ativado ao escrever novas funções ou métodos Go, adicionar cobertura de teste a código existente, criar benchmarks para código crítico de desempenho, implementar testes de fuzzing para validação de entrada ou ao seguir um fluxo de trabalho TDD em projetos Go. O skill detalha o ciclo RED-GREEN-REFACTOR, com exemplos práticos de código, e aborda tópicos como testes orientados por tabela (com e sem casos de erro), subtestes e sub-benchmarks (incluindo execução paralela), funções auxiliares de teste, uso de arquivos golden para comparação de saídas esperadas, mocking baseado em interfaces, benchmarks de diferentes tipos (básicos, com diferentes tamanhos, e de alocação de memória), fuzzing (a partir do Go 1.18), execução de cobertura de teste, e testes para handlers HTTP. O conteúdo é apresentado em português, mantendo os comandos, caminhos de arquivo, nomes de variáveis e blocos de código intactos em inglês para facilitar a aplicação prática em projetos Go.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/golang-testing

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Padrões de Teste em Go

Padrões abrangentes de teste em Go para escrever testes confiáveis e de fácil manutenção seguindo a metodologia TDD.

Quando Ativar

  • Escrevendo novas funções ou métodos em Go
  • Adicionando cobertura de teste a código existente
  • Criando benchmarks para código crítico de desempenho
  • Implementando testes de fuzzing para validação de entrada
  • Seguindo o fluxo de trabalho TDD em projetos Go

Fluxo de Trabalho TDD para Go

O Ciclo RED-GREEN-REFACTOR

RED     → Escreva um teste com falha primeiro
GREEN   → Escreva código mínimo para passar no teste
REFACTOR → Melhore o código mantendo os testes verdes
REPEAT  → Continue com o próximo requisito

TDD Passo a Passo em Go

// Passo 1: Defina a interface/assinatura
// calculator.go
package calculator

func Add(a, b int) int {
    panic("not implemented") // Placeholder
}

// Passo 2: Escreva o teste com falha (RED)
// calculator_test.go
package calculator

import "testing"

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

// Passo 3: Execute o teste - verifique FALHA
// $ go test
// --- FAIL: TestAdd (0.00s)
// panic: not implemented

// Passo 4: Implemente o código mínimo (GREEN)
func Add(a, b int) int {
    return a + b
}

// Passo 5: Execute o teste - verifique PASS
// $ go test
// PASS

// Passo 6: Refatore se necessário, verifique se os testes ainda passam

Testes Orientados por Tabela

O padrão padrão para testes em Go. Permite cobertura abrangente com código mínimo.

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"negative numbers", -1, -2, -3},
        {"zero values", 0, 0, 0},
        {"mixed signs", -1, 1, 0},
        {"large numbers", 1000000, 2000000, 3000000},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Add(tt.a, tt.b)
            if got != tt.expected {
                t.Errorf("Add(%d, %d) = %d; want %d",
                    tt.a, tt.b, got, tt.expected)
            }
        })
    }
}

Testes Orientados por Tabela com Casos de Erro

func TestParseConfig(t *testing.T) {
    tests := []struct {
        name    string
        input   string
        want    *Config
        wantErr bool
    }{
        {
            name:  "valid config",
            input: `{"host": "localhost", "port": 8080}`,
            want:  &Config{Host: "localhost", Port: 8080},
        },
        {
            name:    "invalid JSON",
            input:   `{invalid}`,
            wantErr: true,
        },
        {
            name:    "empty input",
            input:   "",
            wantErr: true,
        },
        {
            name:  "minimal config",
            input: `{}`,
            want:  &Config{}, // Zero value config
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := ParseConfig(tt.input)

            if tt.wantErr {
                if err == nil {
                    t.Error("expected error, got nil")
                }
                return
            }

            if err != nil {
                t.Fatalf("unexpected error: %v", err)
            }

            if !reflect.DeepEqual(got, tt.want) {
                t.Errorf("got %+v; want %+v", got, tt.want)
            }
        })
    }
}

Subtestes e Sub-benchmarks

Organizando Testes Relacionados

func TestUser(t *testing.T) {
    // Setup compartilhado por todos os subtestes
    db := setupTestDB(t)

    t.Run("Create", func(t *testing.T) {
        user := &User{Name: "Alice"}
        err := db.CreateUser(user)
        if err != nil {
            t.Fatalf("CreateUser failed: %v", err)
        }
        if user.ID == "" {
            t.Error("expected user ID to be set")
        }
    })

    t.Run("Get", func(t *testing.T) {
        user, err := db.GetUser("alice-id")
        if err != nil {
            t.Fatalf("GetUser failed: %v", err)
        }
        if user.Name != "Alice" {
            t.Errorf("got name %q; want %q", user.Name, "Alice")
        }
    })

    t.Run("Update", func(t *testing.T) {
        // ...
    })

    t.Run("Delete", func(t *testing.T) {
        // ...
    })
}

Subtestes Paralelos

func TestParallel(t *testing.T) {
    tests := []struct {
        name  string
        input string
    }{
        {"case1", "input1"},
        {"case2", "input2"},
        {"case3", "input3"},
    }

    for _, tt := range tests {
        tt := tt // Capture range variable
        t.Run(tt.name, func(t *testing.T) {
            t.Parallel() // Run subtests in parallel
            result := Process(tt.input)
            // assertions...
            _ = result
        })
    }
}

Auxiliares de Teste

Funções Auxiliares

func setupTestDB(t *testing.T) *sql.DB {
    t.Helper() // Marks this as a helper function

    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        t.Fatalf("failed to open database: %v", err)
    }

    // Cleanup when test finishes
    t.Cleanup(func() {
        db.Close()
    })

    // Run migrations
    if _, err := db.Exec(schema); err != nil {
        t.Fatalf("failed to create schema: %v", err)
    }

    return db
}

func assertNoError(t *testing.T, err error) {
    t.Helper()
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
}

func assertEqual[T comparable](t *testing.T, got, want T) {
    t.Helper()
    if got != want {
        t.Errorf("got %v; want %v", got, want)
    }
}

Arquivos e Diretórios Temporários

func TestFileProcessing(t *testing.T) {
    // Create temp directory - automatically cleaned up
    tmpDir := t.TempDir()

    // Create test file
    testFile := filepath.Join(tmpDir, "test.txt")
    err := os.WriteFile(testFile, []byte("test content"), 0644)
    if err != nil {
        t.Fatalf("failed to create test file: %v", err)
    }

    // Run test
    result, err := ProcessFile(testFile)
    if err != nil {
        t.Fatalf("ProcessFile failed: %v", err)
    }

    // Assert...
    _ = result
}

Arquivos Golden

Testando contra arquivos de saída esperada armazenados em testdata/.

var update = flag.Bool("update", false, "update golden files")

func TestRender(t *testing.T) {
    tests := []struct {
        name  string
        input Template
    }{
        {"simple", Template{Name: "test"}},
        {"complex", Template{Name: "test", Items: []string{"a", "b"}}},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Render(tt.input)

            golden := filepath.Join("testdata", tt.name+".golden")

            if *update {
                // Update golden file: go test -update
                err := os.WriteFile(golden, got, 0644)
                if err != nil {
                    t.Fatalf("failed to update golden file: %v", err)
                }
            }

            want, err := os.ReadFile(golden)
            if err != nil {
                t.Fatalf("failed to read golden file: %v", err)
            }

            if !bytes.Equal(got, want) {
                t.Errorf("output mismatch:\ngot:\n%s\nwant:\n%s", got, want)
            }
        })
    }
}

Mocking com Interfaces

Mocking Baseado em Interface

// Define interface for dependencies
type UserRepository interface {
    GetUser(id string) (*User, error)
    SaveUser(user *User) error
}

// Production implementation
type PostgresUserRepository struct {
    db *sql.DB
}

func (r *PostgresUserRepository) GetUser(id string) (*User, error) {
    // Real database query
}

// Mock implementation for tests
type MockUserRepository struct {
    GetUserFunc  func(id string) (*User, error)
    SaveUserFunc func(user *User) error
}

func (m *MockUserRepository) GetUser(id string) (*User, error) {
    return m.GetUserFunc(id)
}

func (m *MockUserRepository) SaveUser(user *User) error {
    return m.SaveUserFunc(user)
}

// Test using mock
func TestUserService(t *testing.T) {
    mock := &MockUserRepository{
        GetUserFunc: func(id string) (*User, error) {
            if id == "123" {
                return &User{ID: "123", Name: "Alice"}, nil
            }
            return nil, ErrNotFound
        },
    }

    service := NewUserService(mock)

    user, err := service.GetUserProfile("123")
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    if user.Name != "Alice" {
        t.Errorf("got name %q; want %q", user.Name, "Alice")
    }
}

Benchmarks

Benchmarks Básicos

func BenchmarkProcess(b *testing.B) {
    data := generateTestData(1000)
    b.ResetTimer() // Don't count setup time

    for i := 0; i < b.N; i++ {
        Process(data)
    }
}

// Run: go test -bench=BenchmarkProcess -benchmem
// Output: BenchmarkProcess-8   10000   105234 ns/op   4096 B/op   10 allocs/op

Benchmarks com Diferentes Tamanhos

func BenchmarkSort(b *testing.B) {
    sizes := []int{100, 1000, 10000, 100000}

    for _, size := range sizes {
        b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) {
            data := generateRandomSlice(size)
            b.ResetTimer()

            for i := 0; i < b.N; i++ {
                // Make a copy to avoid sorting already sorted data
                tmp := make([]int, len(data))
                copy(tmp, data)
                sort.Ints(tmp)
            }
        })
    }
}

Benchmarks de Alocação de Memória

func BenchmarkStringConcat(b *testing.B) {
    parts := []string{"hello", "world", "foo", "bar", "baz"}

    b.Run("plus", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            var s string
            for _, p := range parts {
                s += p
            }
            _ = s
        }
    })

    b.Run("builder", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            var sb strings.Builder
            for _, p := range parts {
                sb.WriteString(p)
            }
            _ = sb.String()
        }
    })

    b.Run("join", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            _ = strings.Join(parts, "")
        }
    })
}

Fuzzing (Go 1.18+)

Teste de Fuzzing Básico

func FuzzParseJSON(f *testing.F) {
    // Add seed corpus
    f.Add(`{"name": "test"}`)
    f.Add(`{"count": 123}`)
    f.Add(`[]`)
    f.Add(`""`)

    f.Fuzz(func(t *testing.T, input string) {
        var result map[string]interface{}
        err := json.Unmarshal([]byte(input), &result)

        if err != nil {
            // Invalid JSON is expected for random input
            return
        }

        // If parsing succeeded, re-encoding should work
        _, err = json.Marshal(result)
        if err != nil {
            t.Errorf("Marshal failed after successful Unmarshal: %v", err)
        }
    })
}

// Run: go test -fuzz=FuzzParseJSON -fuzztime=30s

Teste de Fuzzing com Múltiplas Entradas

func FuzzCompare(f *testing.F) {
    f.Add("hello", "world")
    f.Add("", "")
    f.Add("abc", "abc")

    f.Fuzz(func(t *testing.T, a, b string) {
        result := Compare(a, b)

        // Property: Compare(a, a) should always equal 0
        if a == b && result != 0 {
            t.Errorf("Compare(%q, %q) = %d; want 0", a, b, result)
        }

        // Property: Compare(a, b) and Compare(b, a) should have opposite signs
        reverse := Compare(b, a)
        if (result > 0 && reverse >= 0) || (result < 0 && reverse <= 0) {
            if result != 0 || reverse != 0 {
                t.Errorf("Compare(%q, %q) = %d, Compare(%q, %q) = %d; inconsistent",
                    a, b, result, b, a, reverse)
            }
        }
    })
}

Cobertura de Teste

Executando Cobertura

# Cobertura básica
go test -cover ./...

# Gerar perfil de cobertura
go test -coverprofile=coverage.out ./...

# Visualizar cobertura no navegador
go tool cover -html=coverage.out

# Visualizar cobertura por função
go tool cover -func=coverage.out

# Cobertura com detecção de race condition
go test -race -coverprofile=coverage.out ./...

Metas de Cobertura

Tipo de CódigoMeta
Lógica de negócio crítica100%
APIs públicas90%+
Código geral80%+
Código geradoExcluir

Excluindo Código Gerado da Cobertura

//go:generate mockgen -source=interface.go -destination=mock_interface.go

// In coverage profile, exclude with build tags:
// go test -cover -tags=!generate ./...

Teste de Handlers HTTP

func TestHealthHandler(t *testing.T) {
    // Create request
    req := httptest.NewRequest(http.MethodGet, "/health", nil)
    w := httptest.NewRecorder()

    // Call handler
    HealthHandler(w, req)

    // Check response
    resp := w.Result()
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        t.Errorf("got status %d; want %d", resp.StatusCode, http.StatusOK)
    }

    body, _ := io.ReadAll(resp.Body)
    if string(body) != "OK" {
        t.Errorf("got body %q; want %q", body, "OK")
    }
}

func TestAPIHandler(t *testing.T) {
    tests := []struct {
        name       string
        method     string
        path       string
        body       string
        wantStatus int
        wantBody   string
    }{
        {
            name:       "get user",
            method:     http.MethodGet,
            path:       "/users/123",
            wantStatus: http.StatusOK,
            wantBody:   `{"id":"123","name":"Alice"}`,
        },
        {
            name:       "not found",
            method:     http.MethodGet,
            path:       "/users/999",
            wantStatus: http.StatusNotFound,
        },
        {
            name:       "create user",
            method:     http.MethodPost,
            path:       "/users",
            body:       `{"name":"Bob"}`,
            wantStatus: http.StatusCreated,
        },
    }

    handler := NewAPIHandler()

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            var bodyReader io.Reader
            if tt.body != "" {
                bodyReader = strings.NewReader(tt.body)
            }

            req := httptest.NewRequest(tt.method, tt.path, bodyReader)
            w := httptest.NewRecorder()

            handler.ServeHTTP(w, req)

            resp := w.Result()
            defer resp.Body.Close()

            if resp.StatusCode != tt.wantStatus {
                t.Errorf("got status %d; want %d", resp.StatusCode, tt.wantStatus)
            }

            if tt.wantBody != "" {
                body, _ := io.ReadAll(resp.Body)
                if string(body) != tt.wantBody {
                    t.Errorf("got body %q; want %q", body, tt.wantBody)
                }
            }
        })
    }
}

Boas Práticas

Convenções de Nomenclatura

ComponentePadrãoExemplo
Arquivo de teste*_test.gocalculator_test.go
Função de testeTestXxx(t *testing.T)TestAdd
Função de benchmarkBenchmarkXxx(b *testing.B)BenchmarkSort
Função de fuzzingFuzzXxx(f *testing.F)FuzzParse
Função auxiliarsetupXxxsetupTestDB
Dados de testeDiretório testdata/testdata/input.json

Organização de Testes

project/
├── .github/
│   └── workflows/
│       └── test.yml
├── internal/
├── pkg/
├── testdata/              # Dados de teste (golden files, fixtures)
│   ├── golden/
│   └── fixtures/
├── integration/           # Testes de integração (opcional)
├── go.mod
├── go.sum
└── Makefile               # Alvos de teste

Exemplo de Makefile

.PHONY: test test-race test-cover bench fuzz

test:
	go test ./... -v -count=1

test-race:
	go test ./... -race -count=1

test-cover:
	go test ./... -coverprofile=coverage.out -count=1
	go tool cover -html=coverage.out

bench:
	go test ./... -bench=. -benchmem

fuzz:
	go test -fuzz=. -fuzztime=30s ./...

Testes em CI/CD

# .github/workflows/test.yml
name: Test
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-go@v5
        with:
          go-version: '1.22'
      - name: Run tests
        run: go test ./... -race -coverprofile=coverage.out -covermode=atomic
      - name: Upload coverage
        uses: codecov/codecov-action@v3

Referência Rápida

Comandos Comuns de Teste

# Executar todos os testes
go test ./...

# Executar testes detalhadamente
go test -v ./...

# Executar testes específicos
go test -run TestAdd ./...

# Executar subtestes específicos
go test -run 'TestUser/Create' ./...

# Executar testes em paralelo
go test -parallel 4 ./...

# Benchmarks
go test -bench=. -benchmem ./...

# Fuzzing
go test -fuzz=. -fuzztime=1m ./...

# Cobertura
go test -cover ./...

# Detecção de race condition
go test -race ./...

# Ultra-rápido (ignora cache)
go test -count=1 ./...

# Short mode para testes rápidos
go test -short ./...

# Compilar mas não executar
go test -run=^$ ./...

Bandeiras de Teste

BandeiraDescrição
-vSaída detalhada
-runExecutar testes correspondentes ao padrão
-countNúmero de execuções (1 desativa cache)
-parallelNúmero de testes paralelos
-shortModo curto (pule testes longos)
-raceHabilitar detecção de race condition
-coverHabilitar cobertura
-coverprofileGravar perfil de cobertura em arquivo
-benchExecutar benchmarks correspondentes ao padrão
-benchmemRelatar alocações de memória em benchmarks
-fuzzExecutar fuzzing correspondente ao padrão
-fuzztimeTempo total para executar fuzzing

Funções de Asserção

// Funções da biblioteca padrão

t.Error(args...)            // Falha, continua execução
t.Errorf(format, args...)   // Falha formatada, continua execução
t.Fatal(args...)            // Falha, para o teste
t.Fatalf(format, args...)   // Falha formatada, para o teste
t.Fail()                    // Marca falha, continua execução
t.FailNow()                 // Marca falha, para o teste
t.Skip(args...)             // Pula o teste
t.Log(args...)              // Log da saída do teste (com -v)
t.Cleanup(func())           // Registra função de limpeza
t.Helper()                  // Marca função como auxiliar
t.Parallel()                // Marca teste para execução paralela
t.TempDir()                 // Cria diretório temporário
t.Setenv(key, value)        // Define variável de ambiente para o teste

Erros Comuns

Ignorar Erros

// Ruim
json.Unmarshal(data, &result)

// Bom
if err := json.Unmarshal(data, &result); err != nil {
    t.Fatalf("unmarshal failed: %v", err)
}

Testes Fracos

// Ruim - testa apenas sem erro
func TestProcess(t *testing.T) {
    err := Process("test")
    if err != nil {
        t.Fatalf("process failed: %v", err)
    }
}

// Bom - testa resultado real
func TestProcess(t *testing.T) {
    result, err := Process("test")
    if err != nil {
        t.Fatalf("process failed: %v", err)
    }
    if result != expectedResult {
        t.Errorf("got %v; want %v", result, expectedResult)
    }
}

Dependência de Ordem de Execução

// Ruim - depende da ordem dos testes
var globalState int

func TestFirst(t *testing.T) {
    globalState = 1
}

func TestSecond(t *testing.T) {
    if globalState != 1 {
        t.Error("globalState should be 1")
    }
}

// Bom - cada teste é independente
func TestFirstIndependent(t *testing.T) {
    state := 1
    // test with state
}

func TestSecondIndependent(t *testing.T) {
    state := 1
    // test with state
}

Não Usar t.Helper()

// Ruim - linha de erro aponta para função auxiliar
func assertNotNil(t *testing.T, val interface{}) {
    if val == nil {
        t.Errorf("value should not be nil")
    }
}

// Bom - linha de erro aponta para o chamador
func assertNotNil(t *testing.T, val interface{}) {
    t.Helper()
    if val == nil {
        t.Errorf("value should not be nil")
    }
}

Lembretes TDD

  • RED: Escreva um teste com falha primeiro
  • GREEN: Escreva código mínimo para passar
  • REFACTOR: Melhore enquanto mantém os testes verdes
  • Pequenos passos: Avance em pequenos incrementos
  • Teste o comportamento: Não teste a implementação
  • Mantenha os testes rápidos: Testes lentos não são executados
  • Uma asserção por teste: Melhor para diagnosticar falhas
  • Nomes descritivos: Os nomes devem descrever o cenário

Etapas do Ciclo TDD

1. Adicione um pequeno teste
2. Execute todos os testes e veja o novo falhar
3. Faça uma pequena alteração
4. Execute todos os testes e veja todos passarem
5. Refatore para remover duplicação
6. (opcional) Atualize listas de pendências
7. Volte ao passo 1

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Habilidades Relacionadas