Unity Test について
Unity Test は、Unity 開発者向けのテスト作成ガイドです。コードを分析して EditMode と PlayMode を選び、NUnit テストを作成します。MonoBehaviour からテスト可能な C# ロジックを分離する方法も扱います。
主な機能
- 01コード分析とテストモードの選択
- 02MonoBehaviour からテスト可能なロジックを抽出
- 03NUnit テストの作成
- 04アセンブリ定義とテストフォルダーの設定案内
- 05テストランナーとトラブルシューティングの案内
活用シーン
- 01純粋な C# ロジックの EditMode テスト作成
- 02シーンのライフサイクルに依存するコードの PlayMode テスト作成
- 03独立してテストできるよう MonoBehaviour のロジックを分離
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ juliankerignard/ unity-skills --skill unity-testインストール後、Claude Code で/unity-testを入力して読み込まれたか確認します。
同梱ファイルreferences/test-templates.md
詳細
Unity Test
このスキルでできること
本番環境で使える Unity テストを生成します。対象コードを分析し、最適なテストタイプ(EditMode または PlayMode)を判断して、テスト可能なロジックを MonoBehaviour から純粋な C# に抽出し、対応する NUnit テストを生成します。
前提条件
- Unity Test Framework:パッケージ
com.unity.test-framework(デフォルトで含まれています) - NUnit:Unity Test Framework に含まれています
- Assembly Definitions:テストフォルダーごとに 1 つの
.asmdef(EditMode と PlayMode は分けます) - プロジェクト構成:
Assets/のルートにTests/フォルダーを作成し、その中にEditMode/とPlayMode/のサブフォルダーを配置します
クイックスタート
- 対象コードを分析します(依存関係、副作用、I/O を特定)
- 判断ツリーを使って EditMode と PlayMode のどちらかを決定します
- コードが MonoBehaviour と密結合している場合は、テスト可能なロジックを抽出します
- 適切なテンプレートに従ってテストを記述します
- Unity Test Runner(
Window > General > Test Runner)で確認します
判断ツリー
Le code a tester...
|
+-- Est de la logique pure (maths, state, data) ?
| +-- EditMode test (rapide, pas besoin de scene)
|
+-- Depend du lifecycle MonoBehaviour (Start, Update, OnCollision) ?
| +-- PlayMode test (simule une scene)
|
+-- Utilise des coroutines ou Awaitable ?
| +-- PlayMode test avec [UnityTest] ou async
|
+-- Valide un ScriptableObject ?
| +-- EditMode test (instancie avec ScriptableObject.CreateInstance)
|
+-- Teste une integration multi-systemes ?
+-- PlayMode Integration test (scene dediee)
主なルール:コードが MonoBehaviour、GameObject、Unity シーンなしで実行できるなら、EditMode テストです。それ以外は PlayMode です。
手順ガイド
ステップ 1:対象コードを分析する
テストを記述する前に、以下を特定します。
- 入力:パラメーター、シリアライズされたフィールド、注入された依存関係
- 出力:戻り値、状態の変化、発行されるイベント
- 副作用:
Destroy、Instantiateの呼び出し、シーンの変更 - Unity の依存関係:
MonoBehaviour、Transform、Physics、Time.deltaTime
ステップ 2:テスト可能なロジックを抽出する
ロジックが MonoBehaviour と密結合している場合は、**「テスト可能な形に抽出する」**パターンを適用します。
// AVANT : logique collee au MonoBehaviour (dur a tester)
public class PlayerHealth : MonoBehaviour
{
[SerializeField] private int maxHealth = 100;
private int currentHealth;
private void Start() => currentHealth = maxHealth;
public void TakeDamage(int amount)
{
currentHealth = Mathf.Max(0, currentHealth - amount);
if (currentHealth <= 0) Die();
}
private void Die() { /* destroy, VFX, etc. */ }
}
// APRES : logique pure extraite (facile a tester en EditMode)
public static class HealthCalculator
{
public static int CalculateDamage(int currentHealth, int damage)
=> Mathf.Max(0, currentHealth - damage);
public static bool IsDead(int health) => health <= 0;
}
// Le MonoBehaviour delegue a la logique pure
public class PlayerHealth : MonoBehaviour
{
[SerializeField] private int maxHealth = 100;
private int currentHealth;
private void Start() => currentHealth = maxHealth;
public void TakeDamage(int amount)
{
currentHealth = HealthCalculator.CalculateDamage(currentHealth, amount);
if (HealthCalculator.IsDead(currentHealth)) Die();
}
private void Die() { /* destroy, VFX, etc. */ }
}
メリット:HealthCalculator はシーンなしで、即座に EditMode でテストできます。
ステップ 3:Assembly Definitions を設定する
2 つの .asmdef ファイルを作成します。
Assets/Tests/EditMode/Game.Tests.EditMode.asmdef—EditorプラットフォームのみAssets/Tests/PlayMode/Game.Tests.PlayMode.asmdef— すべてのプラットフォーム
どちらもゲームのランタイムアセンブリを参照し、defineConstraints に UNITY_INCLUDE_TESTS を設定する必要があります。
完全なテンプレートは references/test-templates.md を参照してください。
ステップ 4:テストを記述する
テストタイプに適したテンプレートに従います。命名規則は次のとおりです。
[MethodName]_[Condition]_[ExpectedResult]
例:
CalculateDamage_NormalHit_ReducesHealthTakeDamage_Overkill_ClampsToZeroStart_OnInitialize_SetsMaxHealth
ステップ 5:実行して確認する
- Unity Test Runner を開きます:
Window > General > Test Runner - EditMode または PlayMode のタブを選択します
Run Allをクリックするか、特定のテストを選択します- カバレッジを確認するには、
Window > Analysis > Code Coverageを開きます
厳守事項
- 必ず
[SetUp]で初期化し、[TearDown]でクリーンアップします - 必ず テストに
MethodName_Condition_ExpectedResultという名前を付けます - 絶対に
Thread.Sleepを使わず、yield return nullまたはawaitを使います - 絶対に EditMode テストでファイルシステムやネットワークにアクセスしません
- 必ず 浮動小数点数には
Assert.AreEqual(expected, actual, tolerance)を使います - 1 テストにつき 1 つの assert(または同じ概念に関する assert のグループ)にします
- Assembly Definitions は必須です。テストをメインアセンブリに入れてはいけません
- 必ず
[TearDown]で、作成した GameObject をObject.DestroyImmediateを使って破棄します - 必ず テストを複製するのではなく、パラメーター化テストには
[TestCase]を使います - 絶対に テスト間に依存関係を持たせません。各テストは独立し、冪等である必要があります
外部フレームワークを使わないモック
Unity にはモックフレームワークが含まれていません。インターフェースと手動のテストダブルを使います。インターフェース(例:IInputProvider)を作成し、設定可能なプロパティを持つモックを実装して、[SerializeField] またはパブリックセッターを介して注入します。
完全な例は references/test-templates.md を参照してください。
関連スキル
/unity-code-gen— コードと同時にテストを生成します/unity-refactor— 既存の MonoBehaviour からテスト可能なロジックを抽出します/unity-debug— テストで修正すべきバグが見つかった場合に使用します/perf-audit— 静的なパフォーマンス監査を行います(実行せずにアンチパターンを検出します)
トラブルシューティング
| 問題 | 考えられる原因 | 解決策 |
|---|---|---|
| テストが検出されない | .asmdef がない、または設定が正しくない | defineConstraints と references を確認します |
| PlayMode が非常に遅い | シーンのセットアップが重すぎる | 最小限にします。空の GameObject を作成し、複雑なプレハブは使いません |
| Async テストがタイムアウトする | CancellationToken が処理されていない | トークンを渡し、最大時間を確認します |
Start で NullReferenceException が発生する | AddComponent の後に yield return null がない | 作成後は必ず 1 フレーム待機します |
| EditMode ではテストが成功するが、ビルドでは失敗する | 条件付きコンパイル #if UNITY_EDITOR | エディター用コードとランタイムコードを分離します |
浮動小数点数の比較で Assert.AreEqual が失敗する | 浮動小数点数を完全一致で比較している | 許容誤差を指定するオーバーロードを使用します:Assert.AreEqual(1.0f, val, 0.001f) |