GGua 日本語リファレンスEnglishGitHub ↗
英語版が正式な参照です。内容に差異がある場合は、英語版を優先してください。
GODOT / TESTING

テストの仕方

Godotプロセスを起動し、ライブなSemantic UI Treeへ接続します。座標ではなくrole・text・idで操作結果を待ちます。

1. 必須NuGetパッケージを入れる

Godotの外部テストにはGua.Core、Gua.Testing、Gua.Testing.Godotの3パッケージが必要です。テストプロジェクトのディレクトリで次を実行します。現在のRelease系列を明示する場合は--version 0.12.0を付けます。

PowerShellpowershell
dotnet add package Gua.Core --version 0.12.0
dotnet add package Gua.Testing --version 0.12.0
dotnet add package Gua.Testing.Godot --version 0.12.0

# NUnitを使う場合
dotnet add package Microsoft.NET.Test.Sdk
dotnet add package NUnit
dotnet add package NUnit3TestAdapter

GodotがPATHにない場合は環境変数を設定します。

PowerShellpowershell
$env:GODOT_EXECUTABLE = "C:\path\to\Godot_v4.7-stable_mono_win64_console.exe"
dotnet test YourGame.Tests.csproj

2. シーンを起動して意味で操作

TitleScreenTests.cscsharp
using Gua.Testing;
using Gua.Testing.Godot;

using var host = GodotSceneTestHost.Load(
    "res://Main.tscn",
    new GodotSceneTestHostOptions {
        ProjectPath = projectPath,
        UseAvailableBridgePort = true,
        StartupResetPolicy = GuaResetPolicy.Strict,
        TeardownResetPolicy = GuaResetPolicy.Strict,
    });

GuaAssertions.GetByRole(
    host.Context, "button", "Start Game"
).ToBeVisible();

await GuaAssertions.GetById(
    host.Context, "start"
).ClickAsync();

await GuaAssertions.WaitForTextAsync(
    host.Context, "loading", "Loading..."
);

3. フォーム操作

非同期アクションcsharp
var name = GuaAssertions.Query(host.Context)
    .ByRole("textbox").Within("LoginForm").Get();

await name.SetValueAsync("alice");
await name.FocusAsync();
await GuaAssertions.PressKeyAsync(host.Context, "Enter");
await GuaAssertions.GetById(host.Context, "RememberMe")
    .SetCheckedAsync(true);
await name.WaitForValueAsync("alice");

安定したテストにする4原則

空きポートを使う

UseAvailableBridgePort = trueで並列テストの衝突を避けます。

厳格にリセット

開始・終了時のStrict resetで未消費要求やイベント漏れを検出します。

待機を使う

固定sleepではなく、状態・値・安定スナップショットを待ちます。

失敗を保存する

UI Tree、ログ、stdout/stderr、任意のPNGを診断成果物へ残します。

1. テストごとに空きポートを確保する

固定の8765を共有すると、並列実行時に一方のGodotだけがポートを取得します。ホストに空きポートを予約させ、子プロセスへGUA_BRIDGE_PORTとして渡します。

空きポートでシーンを起動csharp
using var host = GodotSceneTestHost.Load(
    "res://Main.tscn",
    new GodotSceneTestHostOptions
    {
        ProjectPath = projectPath,
        UseAvailableBridgePort = true,
    });

// 予約されたURLは子プロセスとRemoteContextへ自動設定されます。

2. 開始前と終了前にStrict resetを行う

前のテストが残したノード・要求・イベントを次のテストへ持ち込みません。終了時に未消費の要求やイベントがあれば、黙って削除せずテストを失敗させます。

Strict isolationcsharp
using var host = GodotSceneTestHost.Load(
    "res://Main.tscn",
    new GodotSceneTestHostOptions
    {
        ProjectPath = projectPath,
        UseAvailableBridgePort = true,
        StartupResetPolicy = GuaResetPolicy.Strict,
        TeardownResetPolicy = GuaResetPolicy.Strict,
        CaptureDiagnosticsBeforeTeardown = true,
        CleanupAfterLeakReport = true,
    });

3. Sleepではなく観測したい状態を待つ

Task.Delay(1000)では、速い環境で時間を無駄にし、遅い環境では不足します。操作後に期待するノード状態を直接待ちます。

状態ベースの待機csharp
await GuaAssertions.GetById(host.Context, "start")
    .ClickAsync();

// 表示されるまで最新スナップショットを再取得します。
await GuaAssertions.WaitForVisibleAsync(
    host.Context,
    "loading",
    timeout: TimeSpan.FromSeconds(3),
    pollInterval: TimeSpan.FromMilliseconds(20));

// 描画後の状態が3フレーム変化しないことも確認できます。
await GuaAssertions.WaitForStableSnapshotAsync(
    host.Context,
    stableFrames: 3);

4. アサーション失敗時の診断成果物を設定する

失敗時に最終UI Tree、操作履歴、ログ、Godotのstdout/stderrをartifacts/guaへ保存します。CIではこのディレクトリをテスト成果物としてアップロードします。

失敗診断を有効化csharp
using var diagnostics = host.CreateDiagnosticsSession(
    TestContext.CurrentContext.Test.FullName,
    outputDirectory: Path.Combine(
        TestContext.CurrentContext.WorkDirectory,
        "artifacts", "gua"));

using var assertionScope = GuaAssertionScope.Use(
    new GuaAssertionOptions
    {
        DiagnosticsSession = diagnostics,
    });

// 失敗すると、主例外を保ったまま診断ファイルが保存されます。
GuaAssertions.GetByRole(
    host.Context, "button", "Start Game"
).ToBeVisible();

GitHub Actionsを使う場合は、テスト後にartifacts/gua/**actions/upload-artifactへ渡すと、失敗した実行から診断ファイルを取得できます。

GitHub Actionsで実行する

公開Actionのlink1345/gua-testerを使うと、Windows runnerへのGodot導入、最新の配布済みGuaアドオンの配置、GODOT_EXECUTABLEの設定、dotnet testの実行をまとめて行えます。

.github/workflows/godot-gdscript.ymlyaml
name: Godot Gua UI tests

on:
  pull_request:
  push:
    branches: [main]

jobs:
  test:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run Gua UI tests
        uses: link1345/gua-tester@v1.2
        with:
          project-path: game
          test-project: tests/GuaTester.Tests.csproj
          godot-version: "4.7"
          godot-status: stable