mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 21:53:28 +08:00
6.5 KiB
6.5 KiB
description
| description |
|---|
| Goのテスト駆動開発(TDD)ワークフローを適用します。テーブル駆動テストを最初に記述し、その後実装します。go test -coverで80%以上のカバレッジを確認します。 |
Go TDD コマンド
このコマンドは、Goのイディオム的なテストパターンを使用したテスト駆動開発手法を適用します。
このコマンドの機能
- 型/インターフェースの定義: 関数シグネチャを最初にスキャフォールディング
- テーブル駆動テストの作成: 包括的なテストケースを作成(RED)
- テストの実行: テストが正しい理由で失敗することを確認
- コードの実装: テストをパスするための最小限のコードを記述(GREEN)
- リファクタリング: テストをグリーンに保ちながら改善
- カバレッジの確認: 80%以上のカバレッジを保証
使用するタイミング
/go-test は次の場合に使用します:
- 新しいGo関数の実装時
- 既存コードへのテストカバレッジ追加時
- バグ修正時(失敗するテストを最初に作成)
- 重要なビジネスロジックの構築時
- 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 完了!
## テストパターン
### テーブル駆動テスト
```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/