godot-testing について
Godot 4.3 以降で GUT または gdUnit4 を使う開発者向けのテストスキルです。フレームワークの選択、TDD、テストパターン、ローカルや CI での実行方法を扱います。
主な機能
- 01GUT と gdUnit4 の選択
- 02RED-GREEN-REFACTOR の手順
- 03テスト構成と命名規則
- 04コマンドラインと CI での実行
- 05シーン、シグナル、モック、非同期テスト
活用シーン
- 01GDScript または C# プロジェクトのテスト環境選定
- 02TDD に沿った Godot 機能の実装
- 03ローカルや CI でのテスト実行
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jame581/ godotprompter --skill godot-testingインストール後、Claude Code で/godot-testingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
gdunit4-reference.mdgut-reference.mdreferences/running-tests.mdtdd-workflow.mdtesting-patterns.md詳細
Godot テスト
このスキルでは、GUT(Godot Unit Testing)と gdUnit4 を使用した Godot 4.3 以降のプロジェクトにおけるテスト駆動開発(TDD)を扱います。フレームワークの選定、RED-GREEN-REFACTOR の完全な例、テストの構成、CI でのテスト実行、一般的なテストパターンが含まれます。
関連スキル: レビューチェックリストについては godot-code-review、テストしやすいアーキテクチャについては dependency-injection、CI/CD のテスト自動化については export-pipeline を参照してください。
フレームワークの選定
| 機能 | GUT | gdUnit4 |
|---|---|---|
| 言語 | GDScript を優先、C# は限定的 | GDScript + C#(完全対応) |
| インストール | AssetLib または git submodule | AssetLib または git submodule |
| エディター連携 | GUT パネルを内蔵 | インスペクター + パネルを内蔵 |
| モック | double() / stub() API | mock() / spy() API |
| シーンのテスト | add_child_autofree() | auto_free() + シーンランナー |
| CI サポート | gut_cmdln.gd CLI スクリプト | runtest.sh / GdUnitCmdTool.gd |
| C# サポート | 最小限(GDScript ラッパーのみ) | ネイティブ C# アサーション + ライフサイクル |
| 成熟度 | 実績あり(Godot 3 + 4) | Godot 4 に注力、活発に更新中 |
| 最適な用途 | GDScript のみのプロジェクト | GDScript/C# 混在または C# のみ |
目安: GDScript のみのプロジェクトでは GUT を使用してください。C# プロジェクト、または完全な C# サポートとシーンランナーのユーティリティが必要な場合は、gdUnit4 を使用してください。
TDD ワークフロー:RED-GREEN-REFACTOR
標準的なテスト駆動開発のサイクルです。失敗するテストを書き(RED)、合格する最小限のコードを書き(GREEN)、テストを壊さずにリファクタリングします。各ステップには独自の規律があります。RED を省略すると簡単に通ってしまうテストを書いてしまい、REFACTOR を省略すると技術的負債が積み重なります。
HealthComponent を題材に、3 つのステップすべてを解説した GDScript + C# の実例は、references/tdd-workflow.md を参照してください。
テストディレクトリの構成
res://
├── .gutconfig.json # GUT default config file (optional)
├── src/
│ └── components/
│ ├── health_component.gd
│ └── HealthComponent.cs
└── tests/
├── unit/
│ ├── test_health_component.gd # GUT: test_ prefix (default -gprefix)
│ └── HealthComponentTest.cs # gdUnit4 C#: [TestSuite] attribute
└── integration/
├── test_player_scene.gd
└── PlayerSceneTest.cs
命名規則
| フレームワーク | GDScript ファイル | C# ファイル | テストメソッドの接頭辞/属性 |
|---|---|---|---|
| GUT | test_*.gd | N/A | func test_*() |
| gdUnit4 | 任意の名前(生成時は *_test.gd) | *Test.cs | func test_*() / [TestCase] |
テストの実行
どちらのフレームワークにも CLI ランナーが付属しています。GUT: addons/gut/gut_cmdln.gd は godot --headless --path . -s addons/gut/gut_cmdln.gd -gexit で実行します(-gexit がないと実行が終了しません)。gdUnit4: addons/gdUnit4/runtest.sh -a res://tests(bin/GdUnitCmdTool.gd をラップします。--headless では --ignoreHeadlessMode も必要です)、またはエディターの GdUnit ドックを使用します。CI では、タグまたは PR をトリガーとする GitHub Action で Godot をインストールし、テストスイートを実行します。失敗時はゼロ以外の終了コードを返します。
GUT と gdUnit4 の CLI 実行方法の詳細、およびコピーして使える GitHub Actions ワークフローについては、references/running-tests.md を参照してください。
テストパターン
よく使われるパターンは 4 つあります。ノードを含むシーン(before_each で add_child を使ってインスタンス化し、after_each で解放する)、シグナルのテスト(シグナルの発信が機能すること、接続後に発信すると呼び出されることをアサートする)、モック/ダブル(GDScript では gdUnit4 の mock() を使用し、C# では @export による注入で手動作成したフェイクを使用する)、非同期処理(テスト内で await の yield、シグナル、フレームを待機する)です。
各パターンのコード全体(該当する場合は GDScript + C#)については、references/testing-patterns.md を参照してください。
一般的なアサーション
GUT アサーション
| アサーション | 説明 |
|---|---|
assert_eq(actual, expected) | 等しい |
assert_ne(actual, expected) | 等しくない |
assert_true(value) | 真として評価される |
assert_false(value) | 偽として評価される |
assert_null(value) | null である |
assert_not_null(value) | null ではない |
assert_gt(actual, expected) | より大きい |
assert_lt(actual, expected) | より小さい |
assert_gte(actual, expected) | 以上 |
assert_lte(actual, expected) | 以下 |
assert_has(collection, item) | コレクションに項目が含まれる |
assert_does_not_have(collection, item) | コレクションに項目が含まれない |
assert_string_contains(str, sub) | 文字列に部分文字列が含まれる |
assert_almost_eq(actual, expected, margin) | 許容範囲内で浮動小数点数が等しい |
assert_signal_emitted(obj, signal_name) | シグナルが発行された |
assert_signal_not_emitted(obj, signal_name) | シグナルが発行されなかった |
gdUnit4 アサーション(GDScript + C#)
| GDScript | C# | 説明 |
|---|---|---|
assert_that(val).is_equal(exp) | AssertThat(val).IsEqual(exp) | 等しい |
assert_that(val).is_not_equal(exp) | AssertThat(val).IsNotEqual(exp) | 等しくない |
assert_that(val).is_true() | AssertThat(val).IsTrue() | 真である |
assert_that(val).is_false() | AssertThat(val).IsFalse() | 偽である |
assert_that(val).is_null() | AssertThat(val).IsNull() | null である |
assert_that(val).is_not_null() | AssertThat(val).IsNotNull() | null ではない |
assert_that(val).is_greater(exp) | AssertThat(val).IsGreater(exp) | より大きい |
assert_that(val).is_less(exp) | AssertThat(val).IsLess(exp) | より小さい |
assert_that(val).is_between(min, max) | AssertThat(val).IsBetween(min, max) | 範囲内(両端を含む) |
assert_that(arr).contains([a, b]) | AssertThat(arr).Contains(a, b) | 配列に要素が含まれる |
assert_that(str).contains("sub") | AssertThat(str).Contains("sub") | 文字列に部分文字列が含まれる |
assert_that(val).is_equal_approx(exp, margin) | AssertThat(val).IsEqualApprox(exp, margin) | 許容範囲内の浮動小数点数 |
await assert_signal(mon).is_emitted("name") | await AssertSignal(node).IsEmitted("name") | シグナルが発行された |
テストしないこと
実際のバグを見つけずにノイズを増やすテストは避けてください。
- Godot エンジンの内部処理 —
Node.add_child()が動作することや、@export変数がエディターに表示されることをアサートしないでください - 非公開の実装詳細 — 公開 API を通じて動作をテストしてください。非公開の状態だけを対象とするテストがリファクタリングで失敗するなら、そのテストは間違っています
- 視覚的な出力/レンダリング結果 — ピクセル単位のレンダリング結果は不安定です。代わりに、視覚的な出力を決めるデータをテストしてください
- 許容範囲のない、タイミングに敏感な浮動小数点数 — 物理演算の値には
assert_almost_eq/IsEqualApproxを使用してください - 組み込み機能をラップするだけの1行コード — フィールドを返すだけのプロパティゲッターはテスト不要です
- 考えられるすべての無効な入力 — あらゆる誤用を網羅するのではなく、ドキュメントに記載された契約をテストしてください
チェックリスト
- 各テストファイルが、選択したフレームワークの命名規則に従っている(GUT
test_*.gd、gdUnit4*_test.gd/*Test.cs) - テストが適切な基底クラス(
GutTest/GdUnitTestSuite)を継承している。C# の gdUnit4 スイートは通常の[TestSuite]クラスです - C#:Godot 4.3 では
gdUnit4.apiを 4.3.x に固定します。5.x(Godot 4.4 以降)では、ノードまたはシーンに触れるスイートに[RequireGodotRuntime]を付けます - シーンツリーに追加するノードには
add_child_autofreeまたはauto_freeを使用します。手動でqueue_free()を呼び出すのは禁止です - シグナルは、それを発火させる操作の前に監視を開始します
- テスト対象のユニット自体ではなく、外部依存関係にモック/テストダブルを使用します
- 各テストが1つの動作だけを対象としている(テストごとに論理的なアサーションを1つ)
- CI ワークフローが、プッシュと PR のたびにヘッドレスでテストを実行します
- 不安定な非同期テストでは、任意のスリープ時間ではなく明示的なタイムアウトを使用します
- マージ前にテストが成功している(実装中に限り RED は許容されます)