name: go-test-generator description: Goのテストコードを生成する際に使用。テーブル駆動テスト、testify/assert使用、命名規則TestStructName_MethodNameを適用。Goのユニットテスト、統合テストを書く場合に使用。 allowed-tools: Read, Glob
Go テスト生成パターン
このプロジェクトのGoテスト実装パターンを定義します。
命名規則
- ファイル名:
*_test.go - 関数名:
TestStructName_MethodNameまたはTestFunctionName - パッケージ名:
{package}_test(外部テスト) または{package}(内部テスト)
使用ライブラリ
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
assert: テスト失敗しても続行require: テスト失敗で即座に中断
参照ファイル
テスト実装の参照:
server/internal/repository/user_repository_test.go- Repository テストserver/internal/db/sharding_test.go- シャーディングテストserver/test/integration/- 統合テスト
テストユーティリティ:
server/test/testutil/- テストヘルパー
コードパターン
1. 基本的なテスト
func TestStructName_MethodName(t *testing.T) {
// Arrange
expected := "expected value"
// Act
actual := SomeFunction()
// Assert
assert.Equal(t, expected, actual)
}
2. シャーディング対応のテスト
func TestUserRepository_Create(t *testing.T) {
// テスト用GroupManagerのセットアップ
groupManager := testutil.SetupTestGroupManager(t, 4, 8)
defer testutil.CleanupTestGroupManager(groupManager)
repo := repository.NewUserRepository(groupManager)
ctx := context.Background()
req := &model.CreateUserRequest{
Name: "Test User",
Email: "test@example.com",
}
user, err := repo.Create(ctx, req)
assert.NoError(t, err)
assert.NotNil(t, user)
assert.NotZero(t, user.ID)
}
3. テーブル駆動テスト
func TestHashBasedSharding_GetShardID(t *testing.T) {
tests := []struct {
name string
shardCount int
key int64
wantMin int
wantMax int
}{
{
name: "single shard",
shardCount: 1,
key: 12345,
wantMin: 1,
wantMax: 1,
},
{
name: "multiple shards",
shardCount: 4,
key: 12345,
wantMin: 1,
wantMax: 4,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sharding := db.NewHashBasedSharding(tt.shardCount)
got := sharding.GetShardID(tt.key)
assert.GreaterOrEqual(t, got, tt.wantMin)
assert.LessOrEqual(t, got, tt.wantMax)
})
}
}
4. エラーケースのテスト
func TestUserRepository_GetByID_NotFound(t *testing.T) {
groupManager := testutil.SetupTestGroupManager(t, 4, 8)
defer testutil.CleanupTestGroupManager(groupManager)
repo := repository.NewUserRepository(groupManager)
ctx := context.Background()
// 存在しないIDでテスト
user, err := repo.GetByID(ctx, 999)
assert.Error(t, err)
assert.Nil(t, user)
}
5. require vs assert の使い分け
func TestUserRepository_Update(t *testing.T) {
groupManager := testutil.SetupTestGroupManager(t, 4, 8)
defer testutil.CleanupTestGroupManager(groupManager)
repo := repository.NewUserRepository(groupManager)
ctx := context.Background()
// 前提条件の確認には require を使用(失敗時は即座に中断)
created, err := repo.Create(ctx, createReq)
require.NoError(t, err)
// 本テストの検証には assert を使用
updated, err := repo.Update(ctx, created.ID, updateReq)
assert.NoError(t, err)
assert.Equal(t, "Updated Name", updated.Name)
}
テスト実行コマンド
# 全テスト実行
cd server && APP_ENV=develop go test ./...
# 特定パッケージのテスト
cd server && APP_ENV=develop go test ./internal/repository/...
# 詳細出力
cd server && APP_ENV=develop go test -v ./...
# カバレッジ
cd server && APP_ENV=develop go test -cover ./...