mcpField
G
go-testing

go-testing

github.com/autumnsgrove测试与质量671 次安装5 天前更新
代码仓库

关于 go-testing

面向 Go 开发者的测试技能,介绍编写和运行测试的方法,涵盖惯用测试模式、基准测试与模糊测试。

主要功能

  1. 01表驱动测试与子测试
  2. 02测试辅助函数与清理
  3. 03基于接口的依赖模拟
  4. 04HTTP 处理器测试
  5. 05基准测试与模糊测试

适用场景

  1. 01为 Go 包编写测试
  2. 02测试 HTTP 处理器
  3. 03对 Go 代码进行基准或模糊测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/autumnsgrove/lattice --skill go-testing

安装后在 Claude Code 中输入/go-testing确认已加载。

详细介绍

Go 测试技能

何时启用

在以下情况下启用此技能:

  • 编写 Go 单元测试
  • 创建表驱动测试
  • 使用测试辅助函数和测试夹具
  • 通过接口模拟依赖项
  • 运行基准测试或模糊测试

快速命令

# Run all tests
go test ./...

# Verbose output
go test -v ./...

# Run specific test
go test -run TestUserCreate

# With coverage
go test -cover ./...
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out

# Run benchmarks
go test -bench=. ./...

# Race detector
go test -race ./...

基本测试结构

// math_test.go
package math

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)
    }
}

表驱动测试(惯用 Go 写法)

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

    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)
            }
        })
    }
}

子测试和并行执行

func TestAPIEndpoints(t *testing.T) {
    tests := []struct {
        name     string
        endpoint string
        status   int
    }{
        {"health", "/health", 200},
        {"users", "/api/users", 200},
    }

    for _, tt := range tests {
        tt := tt // capture range variable
        t.Run(tt.name, func(t *testing.T) {
            t.Parallel() // run in parallel
            // test logic
        })
    }
}

测试辅助函数

func assertEqual(t *testing.T, got, want int) {
    t.Helper() // marks as helper for line numbers
    if got != want {
        t.Errorf("got %d; want %d", got, want)
    }
}

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

设置和清理

func TestDatabase(t *testing.T) {
    // Setup
    db := setupTestDB(t)

    // Teardown (runs after test)
    t.Cleanup(func() {
        db.Close()
    })

    // Test code
    user, err := db.CreateUser("[email protected]")
    assertNoError(t, err)
}

使用接口模拟

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

// Mock implementation
type MockUserRepo struct {
    FindByIDFunc func(id string) (*User, error)
}

func (m *MockUserRepo) FindByID(id string) (*User, error) {
    return m.FindByIDFunc(id)
}

// Test with mock
func TestUserService_GetUser(t *testing.T) {
    mock := &MockUserRepo{
        FindByIDFunc: func(id string) (*User, error) {
            return &User{ID: "123", Email: "[email protected]"}, nil
        },
    }

    service := &UserService{repo: mock}
    user, err := service.GetUser("123")

    assertNoError(t, err)
    assertEqual(t, user.ID, "123")
}

HTTP 处理程序测试

import (
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestHealthHandler(t *testing.T) {
    req := httptest.NewRequest("GET", "/health", nil)
    rr := httptest.NewRecorder()

    handler := http.HandlerFunc(HealthHandler)
    handler.ServeHTTP(rr, req)

    if rr.Code != http.StatusOK {
        t.Errorf("status = %d; want %d", rr.Code, http.StatusOK)
    }
}

基准测试

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

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

目录结构

project/
├── internal/
│   ├── user/
│   │   ├── user.go
│   │   └── user_test.go
│   └── api/
│       ├── handler.go
│       └── handler_test.go
└── test/
    └── integration/
        └── api_test.go

测试函数签名

func TestXxx(t *testing.T)      // Regular test
func BenchmarkXxx(b *testing.B) // Benchmark
func ExampleXxx()               // Example (docs)
func FuzzXxx(f *testing.F)      // Fuzz test

相关资源

请参阅 AgentUsage/testing_go.md,获取完整文档,其中包括:

  • 模糊测试模式
  • 测试类型的构建标签
  • 用于包级设置的 TestMain
  • CI 中的覆盖率

评论

支持 Markdown