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

Visualテスト実践

Gua.Testing.Visualを使うと、実行中ゲームのscreenshotをreview済みPNG baselineと比較し、Controlの重なり、clipping、位置ずれ、誤ったassetやthemeなどを検出できます。Semantic UI上では正しく存在するのに表示が壊れている問題を見つけるために必要な、game engine非依存のVisual regressionテストです。

どんな不具合に使うか

Visualが有効Semantic assertionを優先
Controlのclipping・重なり・位置ずれbuttonが存在する、visibleである
誤ったtexture、font、theme、overlaytextやvalueが期待値である
解像度変更で崩れたlayout操作後に画面・状態が遷移した
描画は成功したが見た目が異なる高速で原因が明確な機能検証
Stable UI frame必要なら3 frame待機Actual PNGdiagnosticsから取得Reviewed baselinename + variantPixel comparisonthreshold・maskPASS / artifacts差分をreview
図1: baselineはテスト名とvariantで選ばれ、許容条件を超えた場合だけ比較artifactを生成します。

導入

最新安定版をvisual test projectへ追加powershell
dotnet add package Gua.Testing.Visual

1. baselineを明示的に作る

baselineが無い通常実行は失敗します。初回または意図したUI変更時だけ、developerが明示的に更新します。

PowerShellでbaseline更新を許可powershell
$env:GUA_UPDATE_BASELINES = "1"
dotnet test tests/Game.Visual.Tests/Game.Visual.Tests.csproj
Remove-Item Env:GUA_UPDATE_BASELINES

生成されたPNGを目視reviewし、正しい場合だけtest repositoryへcommitします。通常のpull request jobにこの環境変数を設定してはいけません。

2. baselineをversion管理する

次の比較例はNUnitのtest output directoryからbaselineを読みます。test project直下のbaselinesへcommitしたPNGがclean checkoutやCIでもoutputへコピーされるよう、project fileへ次のruleを追加します。

Game.Visual.Tests.csprojxml
<ItemGroup>
  <None Update="baselines/**/*.png"
        CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

baselineを作成・更新した場合は、outputに生成されたPNGを目視reviewし、承認したファイルをproject直下のbaselinesへ戻してからcommitしてください。

3. 通常実行で比較する

title画面を比較csharp
using Gua.Testing;
using Gua.Testing.Visual;

// 遷移とanimationが決定的になった後だけgame側が公開するnode
await GuaAssertions.WaitForVisibleAsync(host.Context, "visual-ready");

var baselineVariant = Environment.GetEnvironmentVariable("GUA_VISUAL_VARIANT")
    ?? "windows-unity-mono-1920x1080";

var result = await GuaVisualAssertions.ExpectScreenshotAsync(
    host.Context,
    "title-screen",
    new ScreenshotOptions
    {
        BaselineDirectory = Path.Combine(TestContext.CurrentContext.TestDirectory, "baselines"),
        ArtifactDirectory = Path.Combine(TestContext.CurrentContext.WorkDirectory, "artifacts", "gua"),
        BaselineVariant = baselineVariant,
        PixelThreshold = 0.02f,
        MaxDifferentPixelRatio = 0.001,
        WaitForStableSnapshot = true,
        StableFrames = 3,
    });

WaitForStableSnapshotが確認するのはSemantic UI snapshotが変化しなくなったことだけです。sprite、shader、caret、画面遷移等のpixel animation停止は検出しません。上の例のようにapplication固有のready条件を先に待ち、animation状態を決定的にしてください。PixelThresholdは各channelの微差、MaxDifferentPixelRatioは差があるpixelの割合を許容します。最初から大きな値を設定せず、renderer由来の安定した差だけを根拠に調整します。

失敗時に残るもの

理由ファイル
pixel_differenceexpected.pngactual.pngdiff.pngcomparison.json
baseline_missingactual.pngcomparison.json
dimension_mismatchexpected.pngactual.pngcomparison.json

ArtifactDirectoryを指定すれば、通常のGua diagnosticsと同じ失敗directoryへVisual artifactをまとめられます。dimension mismatchは暗黙にresizeせず失敗します。Gua.Testing.Visualはデータだけを出力してHTMLを生成しません。静的Viewerの構築にはvisual-report Actionを使います。

variantとmask

設定使い方避けること
BaselineVariantOS、engine、renderer、解像度など正当な描画差を名前へ含める失敗するたび新variantを増やす
Masks時計、乱数avatarなど本当に非決定的な矩形だけ除外重要UI全体をmaskして回帰を隠す
WaitForStableSnapshotapplication-ready条件の後、Semantic stateが変化しないことを確認pixel animationを停止・検出できると仮定する
非決定領域を限定してmaskcsharp
Masks = new[]
{
    new GuaMaskRectangle(X: 1710, Y: 24, Width: 180, Height: 48), // clock only
};

CI運用

PRで閲覧可能なレポートを保存yaml
- name: Run visual tests
  id: visual-tests
  shell: pwsh
  env:
    GUA_VISUAL_VARIANT: windows-unity-mono-1920x1080
  run: dotnet test tests/Game.Visual.Tests/Game.Visual.Tests.csproj --configuration Release

- name: Upload visual report
  if: failure()
  uses: link1345/gua-tester/visual-report@v2.2
  with:
    artifact-path: artifacts/gua
    test-outcome: failure
    upload-target: workflow

CIでは解像度、DPI scaling、font、locale、theme、engine version、renderer、GPU/driver policyを固定します。baseline更新は通常jobから分離し、差分reviewを必須にします。