跳转至

Go TDD 命令

此命令应用使用 Go 惯用测试模式的测试驱动开发方法。

此命令的功能

  1. 类型/接口定义:首先为函数签名搭建脚手架
  2. 创建表驱动测试:创建全面的测试用例(RED)
  3. 运行测试:确认测试因正确的原因失败
  4. 实现代码:编写使测试通过的最小代码(GREEN)
  5. 重构:在保持测试通过的同时进行改进
  6. 检查覆盖率:保证 80% 以上的覆盖率

使用时机

/go-test 在以下情况下使用: - 实现新的 Go 函数时 - 为现有代码添加测试覆盖率时 - 修复 bug 时(先创建失败的测试) - 构建关键业务逻辑时 - 学习 Go 中的 TDD 工作流时

TDD 循环

RED     → 失敗するテーブル駆動テストを作成
GREEN   → テストをパスするための最小限のコードを実装
REFACTOR → コードを改善、テストはグリーンを保持
REPEAT  → 次のテストケースへ

会话示例

User: /go-test メールアドレスを検証する関数が必要です

Agent:
# TDD セッション: メールバリデーター

## ステップ 1: インターフェースの定義

```go
// validator/email.go
package validator

// ValidateEmail checks if the given string is a valid email address.
// Returns nil if valid, error describing the issue otherwise.
func ValidateEmail(email string) error {
    panic("not implemented")
}

ステップ 2: テーブル駆動テストの作成 (RED)

// validator/email_test.go
package validator

import (
    "testing"
)

func TestValidateEmail(t *testing.T) {
    tests := []struct {
        name    string
        email   string
        wantErr bool
    }{
        // 有効なメールアドレス
        {"simple email", "user@example.com", false},
        {"with subdomain", "user@mail.example.com", false},
        {"with plus", "user+tag@example.com", false},
        {"with dots", "first.last@example.com", false},

        // 無効なメールアドレス
        {"empty string", "", true},
        {"no at sign", "userexample.com", true},
        {"no domain", "user@", true},
        {"no local part", "@example.com", true},
        {"double at", "user@@example.com", true},
        {"spaces", "user @example.com", true},
        {"no tld", "user@example", true},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            err := ValidateEmail(tt.email)
            if tt.wantErr && err == nil {
                t.Errorf("ValidateEmail(%q) = nil; want error", tt.email)
            }
            if !tt.wantErr && err != nil {
                t.Errorf("ValidateEmail(%q) = %v; want nil", tt.email, err)
            }
        })
    }
}

ステップ 3: テストの実行 - 失敗を確認

$ go test ./validator/...

--- FAIL: TestValidateEmail (0.00s)
    --- FAIL: TestValidateEmail/simple_email (0.00s)
        panic: not implemented

FAIL

✓ テストが期待通り失敗しました(panic)。

ステップ 4: 最小限のコード実装 (GREEN)

// validator/email.go
package validator

import (
    "errors"
    "regexp"
)

var emailRegex = regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)

var (
    ErrEmailEmpty   = errors.New("email cannot be empty")
    ErrEmailInvalid = errors.New("email format is invalid")
)

func ValidateEmail(email string) error {
    if email == "" {
        return ErrEmailEmpty
    }
    if !emailRegex.MatchString(email) {
        return ErrEmailInvalid
    }
    return nil
}

ステップ 5: テストの実行 - パスを確認

$ go test ./validator/...

PASS
ok      project/validator    0.003s

✓ すべてのテストが通りました!

ステップ 6: カバレッジの確認

$ go test -cover ./validator/...

PASS
coverage: 100.0% of statements
ok      project/validator    0.003s

✓ カバレッジ: 100%

TDD 完了!

## 测试模式 {#test-patterns}

### 表驱动测试 {#table-driven-tests}
```go
tests := []struct {
    name     string
    input    InputType
    want     OutputType
    wantErr  bool
}{
    {"case 1", input1, want1, false},
    {"case 2", input2, want2, true},
}

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

并行测试

for _, tt := range tests {
    tt := tt // Capture
    t.Run(tt.name, func(t *testing.T) {
        t.Parallel()
        // test body
    })
}

测试辅助函数

func setupTestDB(t *testing.T) *sql.DB {
    t.Helper()
    db := createDB()
    t.Cleanup(func() { db.Close() })
    return db
}

覆盖率命令

# 基本的なカバレッジ
go test -cover ./...

# カバレッジプロファイル
go test -coverprofile=coverage.out ./...

# ブラウザで表示
go tool cover -html=coverage.out

# 関数ごとのカバレッジ
go tool cover -func=coverage.out

# レース検出付き
go test -race -cover ./...

覆盖率目标

代码类型 目标
关键业务逻辑 100%
公共 API 90%+
一般代码 80%+
生成的代码 排除

TDD 最佳实践

推荐事项: - 在实现之前先编写测试 - 每次更改后运行测试 - 使用表驱动测试以获得全面覆盖 - 测试行为而非实现细节 - 包含边界情况(空、nil、最大值)

应避免的事项: - 在测试之前编写实现 - 跳过 RED 阶段 - 直接测试私有函数 - 在测试中使用 time.Sleep - 忽略不稳定的测试

  • /go-build - 修复构建错误
  • /go-review - 实现后的代码审查
  • /verify - 运行完整验证循环
  • 技能: skills/golang-testing/
  • 技能: skills/tdd-workflow/

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 ev/ECC