go-test
fsmによる状態遷移のサンプル
Install / Use
npx skills add mormorbump/FsmStateMachineSampleInstalls into whichever agent you are using.
.clinerules
Cline rules
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Skill content
View source on GitHubGo Practice
モジュールを追加する
モジュールを追加するとき、 go.mod にすでに require されていないか確認する。
一般によく知られているモジュール以外をコードに追加するときは、ハルシネーションをしていないか確認する。
モジュールが見つかった場合、 go get -tool <name> で go.mod に追加し、各ファイルでimport して使う。
テストの書き方
testifyパッケージを使用
package calculator
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAddition(t *testing.T) {
// テスト対象の関数を実行
result := Add(2, 3)
// 期待値の検証 (testifyを使用)
assert.Equal(t, 5, result, "数値の合計が期待値と一致すること")
}
テストの基本原則
- テストファイルは
_test.goのサフィックスをつける testify/assertまたはtestify/requireパッケージを利用する- テスト関数は必ず
Testから始まる名前にする - テスト関数は
t *testing.Tパラメータを受け取る - 複雑な入れ子構造は避け、
t.Run()を使用して平坦な構造にする
アサーションの書き方
// 等値比較
assert.Equal(t, expected, actual, "期待値と一致すること")
// 真偽値の検証
assert.True(t, condition, "条件が真であること")
// nilチェック
assert.Nil(t, object, "オブジェクトがnilであること")
assert.NotNil(t, object, "オブジェクトがnilでないこと")
必ず失敗時のメッセージを含めて、何をテストしているかを明確にする
サブテストを使った例
func TestCalculator(t *testing.T) {
t.Run("Addition", func(t *testing.T) {
result := Add(2, 3)
assert.Equal(t, 5, result, "2+3の計算結果が5になること")
})
t.Run("Subtraction", func(t *testing.T) {
result := Subtract(5, 2)
assert.Equal(t, 3, result, "5-2の計算結果が3になること")
})
}
テーブル駆動テストの基本
package calculator
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestAdd(t *testing.T) {
// テストケースのテーブル定義 - データの部分
tests := []struct {
name string
a int
b int
expected int
}{
{name: "正の数同士", a: 2, b: 3, expected: 5},
{name: "正と負の数", a: 2, b: -3, expected: -1},
{name: "負の数同士", a: -2, b: -3, expected: -5},
{name: "ゼロを含む", a: 0, b: 5, expected: 5},
}
// テストロジックの部分 - 各テストケースを実行
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
assert.Equal(t, tt.expected, result, "計算結果が期待値と一致すること")
})
}
}
データとロジックの分離
テーブル駆動テストの核心は「データとロジックの分離」:
-
テーブル部分(データ):
- 入力パラメータと期待される出力のみに集中
- 実装の詳細ではなく、外部から見た振る舞いをテスト
-
テスト部分(ロジック):
- テストの実行方法は一箇所にまとめる
- 全てのテストケースに対して同じロジックを適用
テーブルの設計ポイント
効果的なテーブル設計のために重要な2つの観点:
-
適切なテストケース数:
- 少なすぎると網羅性に欠ける
- 多すぎると可読性が低下
- 境界値、エッジケース、通常ケースを含める
- 目安として5〜10ケース程度が読みやすい
-
入出力への集中:
- テーブルには入力と期待される出力のみを含める
- テスト中の中間状態や内部実装の詳細は含めない
- 「何を入れたら何が出るか」という観点でテストケースを設計
実践例
func TestCalculate(t *testing.T) {
// データとしてのテストケース - 入力と出力のみに集中
tests := []struct {
name string // テストケースの名前
expression string // 入力
expected float64 // 期待される出力
expectError bool // エラーが予想されるか
}{
{name: "基本的な加算", expression: "2+3", expected: 5, expectError: false},
{name: "複雑な式", expression: "2*3+4", expected: 10, expectError: false},
{name: "ゼロ除算", expression: "5/0", expected: 0, expectError: true},
{name: "空の式", expression: "", expected: 0, expectError: true},
{name: "不正な文字", expression: "2+a", expected: 0, expectError: true},
}
// ロジックとしてのテスト実行部分
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Calculate(tt.expression)
// エラー期待値のチェック
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
assert.Equal(t, tt.expected, result)
}
})
}
}
テーブル駆動テストの利点
- コードの重複を減らす
- テストケースの追加が容易
- 異なるインプットでの挙動を一目で確認できる
- メンテナンス性が高い
- データとロジックが分離されているため、テストの意図が明確
適切なテーブル設計と入出力への集中を意識することで、読みやすく保守性の高いテストを実現できます。これはGoの標準的なテスト手法として広く採用されています。
Goパッケージ構造のベストプラクティス
依存関係の管理
-
パッケージ設計:
- より小さく、集中したパッケージに分割
- 依存方向を上位レベル(アプリケーション)から下位レベル(ユーティリティ)に向ける
- 依存性逆転の原則を使用して、インターフェースを介した疎結合を実現
-
依存関係可視化ツール:
go mod graph- モジュール依存関係の表示go mod why- なぜ特定の依存関係が必要なのかを表示- サードパーティツール:
go get -tool github.com/loov/goda@latest goda graph ./...
Go特有のベストプラクティス
-
依存関係の検証ツール:
go vet- 潜在的な問題をチェックgolangci-lint- 複数のリンターを統合
golangci-lint run --enable=depguard,gomoddirectives -
インターフェース設計:
- インターフェースは実装側ではなく使用側のパッケージで定義
- これにより依存方向を制御し循環参照を防ぐ
-
依存性注入:
- コードの依存関係をより明示的に、テスト可能に
wireやfxなどのDIフレームワークを活用
Goにおけるコード品質の監視
カバレッジ
Goでのテストカバレッジの取得は次のように行う:
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
上記コマンドで、HTML形式のカバレッジレポートが生成され、ブラウザで詳細を確認できる。
カバレッジの目標値:
- 新規実装時は80%以上のカバレッジを目標とする
- 重要なビジネスロジックは90%以上を目指す
デッドコード解析
Goでのデッドコード検出には以下のツールが利用する:
# deadcode検出
go get -tool golang.org/x/tools/cmd/deadcode@latest
deadcode ./...
# 未使用の依存関係検出
go mod tidy
# より高度な静的解析
go get -tool honnef.co/go/tools/cmd/staticcheck@latest
staticcheck ./...
継続的インテグレーションで以下のようなコマンドを実行するよう設定:
# CIでのデッドコード検出
go vet ./...
staticcheck ./...
これまでのコマンドは、全てMakefileで実行可能
Related Skills
career-ops
72.3kOpen-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)
ai-job-search
43.5kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
41.6kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
guizang-ppt-skill
26.7kAI-agent Skill for generating polished HTML slide decks: editorial magazine and Swiss layouts, image prompts, social covers, and a WebGL/low-power presentation runtime.
Security Score
Audited on Invalid Date
