やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

BannedApiAnalyzers.Unity を公開しました

Microsoft.CodeAnalysis.BannedApiAnalyzers は、プロンプトで使用を禁止したいAPIを設定ファイルに書くことでコンパイル時に診断できるRoslynアナライザです。

もちろんUnityでも使用できますが、Unityでは自動生成される .csproj ファイルに設定ファイルのパスを追加する必要があります。 これはエディタスクリプトで .csproj ファイル生成をフックして書き換えれば実現できますが、少し面倒です。

このエディタスクリプト実装が不要になるようフォークして変更した BannedApiAnalyzers.Unity を作ったので紹介します。

github.com

nugte.org にも公開済みです。

www.nuget.org

BannedApiAnalyzers.Unity の利点

.csproj ファイルの書き換えが不要

素の Microsoft.CodeAnalysis.BannedApiAnalyzers では、設定ファイルとして BannedSymbols.txt もしくは BannedSymbols.\*.txt を要求します。 ファイル名は固定ですが、ファイルパスを .csproj ファイルに AdditionalFiles として追加しなければなりません。

一方、Unityでは2021.3から、特定のファイルパスを .csproj ファイルに AdditionalFiles として追加する機能が使えます*1。 しかしファイル名に制約があり、Filename.[Analyzer Name].additionalfile フォーマットでないと処理されません。つまり、BannedSymbols.txt というファイルをアナライザに渡す手段はありません。

BannedApiAnalyzers.Unity は、UnityのAdditional files機能で渡されたファイルを設定ファイルとして読みます。 つまり、プロジェクトの Assets/ 下に <Filename>.BannedApiAnalyzers.Unity.additionalfile という名前のファイルを置くだけで、禁止するAPIを指定できます。

なお、次の点に注意してください。

  • <Filename> 部分は必須で、かつ途中にピリオドを含んではいけません
  • Assets/ 直下だけでなくサブディレクトリのどこに置いたファイルでも、プロジェクト全体に適用されます。ディレクトリやアセンブリごとに設定を使い分けることはできません
  • Packages/ 下にある組み込みパッケージにも適用されます

v3.11 ベース

nuget.orgに公開されている Microsoft.CodeAnalysis.BannedApiAnalyzers は v3.3.4 です。 次バージョンである v3.11 は安定版をリリースされないまま dotnet/roslyn に統合され、パッケージとしての公開はされていません。

BannedApiAnalyzers.Unity は、v3.11 のソースをベースにしています。v3.3.4 との差異は次のとおりです(Claude Code調べ)。

新機能(v3.11.0 で追加)
機能 概要
名前空間の ban 対応 BannedSymbols.txtN:SomeNamespace と書くと、そのネームスペース内のすべての型参照に RS0030 が発火する。v3.3.4 では未対応(エントリが無視された)。
継承元の ban 検出 class Derived : BannedBase {} のような継承構文に対しても RS0030 が発火するようになった。Base-type syntax node への RegisterSyntaxNodeAction が追加。
// コメントのサポート BannedSymbols.txt で行末に // 説明 と書けるようになった。v3.3.4 では // 以降が DocumentationCommentId の一部として解釈され、シンボル解決が静かに失敗していた。
内部変更(挙動に影響する可能性あり)
変更 影響
シンボル解決の遅延化 解決を Lazy<ImmutableArray<ISymbol>> に変更。パフォーマンス改善で機能差異はほぼないが、曖昧な ID のエッジケースで挙動が変わる可能性あり。
重複検出ロジック変更 v3.3.4: 解決済み ISymbol オブジェクトの比較。v3.11.0: 生の DeclarationId 文字列(trim 後)で grouping。未解決シンボルでも重複が検出されるように。

使いかた

インストール

アナライザのインストールは、NuGetForUnity か UnityNuGet (OpenUPM)*2 からがおすすめです。

NuGetForUnity の場合、次の手順でインストールすると、全アセンブリに適用されます。

  1. Open the NuGetForUnity window via NuGet > Manage NuGet Packages
  2. Search "BannedApiAnalyzers.Unity" and click Install

UnityNuGet の場合、openupmコマンドかPackage Managerウィンドウでインストールしてから、適用させたいアセンブリの Assembly Definition References に BannedApiAnalyzers.Unity_Unity を追加します。

openupm add org.nuget.BannedApiAnalyzers.Unity

NuGetForUnity と UnityNuGet の違いについて詳しくは、次の記事を参照してください。

www.nowsprinting.com

設定ファイル

Assets/ 下の任意のディレクトリに設定ファイルを作ります。ファイル名はフォーマット <Filename>.BannedApiAnalyzers.Unity.additionalfile を守る必要があります。

設定ファイルにはDocumentation Comment ID形式で禁止したいAPIを列挙します。書式は ID string format を参照してください。

たとえば、Assets/BannedSymbols.BannedApiAnalyzers.Unity.additionalfile に次のように書きます。

M:UnityEngine.GameObject.Find(System.String)

すると、次のように GameObject.Find(string) メソッドの使用箇所で警告が出ます。

なお、Documentation Comment ID の後ろに ; を挟んでメッセージを書けるので、どう書き換えるべきかを書いておくとよいでしょう。特にAI Coding Agentを使用するなら必須といえます。

補足

重大度の変更

デフォルトでは、BannedApiAnalyzers.Unity による診断の重大度(severity)は Warning です。 これは .ruleset.globalconfig、もしくは .editorconfig ファイルで変更できます。詳しくは、それぞれ過去記事を参照してください。

www.nowsprinting.com

www.nowsprinting.com

サポートUnityバージョン

BannedApiAnalyzers.Unityが動作するのは、Unity 2021.2 以降です。 Additional files 機能が(おそらく)Unity 2021.3 からなので、それに合わせてあります。

*1:https://docs.unity3d.com/Manual/roslyn-analyzers-additional-files.html

*2:執筆時点ではOpenUPMはリリース待ち

Unityプロジェクトでテスト設計+テストファースト開発のための Agent Skills

昨年、Unityプロジェクトでも Claude Code に自走させるワークフロー という記事を投稿しました。 その後も .claude/ 下を公開したリポジトリのメンテナンスを継続していましたが、改めて Agent Skills/ Claude Code プラグインとして公開しました。

github.com

実装計画スキル

代表スキルは /plan-feature <SPEC> で、これをプランモードで使用すると実装前にテスト設計を行い、プランファイルにテストケースを含めてくれます。また実装をテストファースト(TDDではなく)で進めるワークフローもプランファイルに含めます。

このスキルおよびワークフローには、次の特徴があります。

  • テスト設計
    • 保守性の高いテスト:AIが書きがちな、冗長なテスト、アサーションのないテスト、不要なテストダブル(モック/ スタブなど)を削減
    • 手動検証は最低限:統合テストレイヤでUI操作を含めたテストを実施、目視検証が必要なテストは画像解析による検証を実施*1。アニメーションや手触り感などの観点のみ人間に評価を移譲
    • プラン時点でテストケースをレビュー可能:検証内容も含めてプランファイルに出力されるので、テストケースをレビューすることでプランが仕様を満たしているかどうか判断できる
  • テストファースト
    • テストコードを先に実装・実行して、テストが失敗することを確認します。テストファーストには次の利点があります
      • テストコードの正当性(少なくとも、ちゃんと失敗できるテストである)が担保される
      • プロダクトコード(ゲーム本体コード)実装の完了基準を定義できる
      • テスト駆動開発(TDD)と比べ、変更ループが少なくトークン消費も抑えられる
  • コーディングガイドライン
    • Unity Test Framework向けテスト実装についてのガイドライン(非同期テストは UnityTest 属性でなく async + Test 属性を使う、など)
    • Unity向けコード実装についての最低限のガイドライン(Unity 2021.1以降ではオブジェクトプーリングを自前実装しないで ObjectPool<T> を使う、など)
    • Scene/ Prefab の編集は、エディタスクリプトをアドホックに書いてUnityエディタで実行
    • ScriptableObject などの複雑でないアセットファイルを直接編集するガイドライン
  • 内部品質(保守性・可読性など)
    • テスト可能なコードであるという点で、最低限の内部品質は確保
    • ワークフローの最後に、決定論的ツールによる静的解析を実行(後述)

インストールと設定

プラグイン/ スキルのインストール

Claude Code プラグインとしてプロジェクトスコープにインストールする場合は、次のスラッシュコマンドを実行します。

/plugin marketplace add nowsprinting/unity-coding-skills
/plugin install unity-coding-skills@nowsprinting-unity-coding-skills --scope project

その他、スキル単位でインストールするツールなどが使えるはずです。

MCPサーバの設定

一部のスキルは、JetBrains RiderビルトインのMCPサーバ及び、Unityエディタを操作する拡張を使用します。 設定方法は次の記事を参照してください。 なお、設定ファイルを手書きする場合は、MCPサーバの名称は必ず jetbrains にしてください。

www.nowsprinting.com

Riderを使いたくない場合、一部のスキルだけ書き換えてもらえれば動作はするはずです。 しかし、JetBrains MCPサーバにはファイル検索などCoding Agentを効率化するツールも含まれていますので、Riderの使用をお勧めします。 無料トライアルもあります。

静的解析の設定

強制したいコーディングルールは、コンパイラやRoslynアナライザで warning 以上の診断になるように設定しておくと、ワークフローの最終フェーズで修正されます。

たとえば、(AIがやりがちな)変更で使わなくなった型やメンバを削除せず放置するのを禁止するには、次の設定を .editorconfig ファイルに追加します。

resharper_unused_type_local_highlighting = warning
resharper_unused_type_global_highlighting = warning
resharper_unused_member_global_highlighting = warning
resharper_unused_member_local_highlighting = warning

.editorconfig ファイルについて詳しくは次の記事を参照してください。

www.nowsprinting.com

またRiderを使用できる場合、プラグインによる診断も対象になります。 (これもAIが書きがちな)長く複雑なメソッドを分割させるために、サイクロマティック/ コグニティブ複雑度を診断するプラグインが利用できます。 詳しくは次の記事を参照してください。

www.nowsprinting.com

注意事項

  • ドキュメントに "TBD" と書いてある仕様は無視されます(詳細を詰められたりしない)
  • Scene/ Prefab 編集スクリプトは、コミットも削除もしません(中身を見たいことがあるため)
  • スキルにはコーディング規約を含まないため、たとえば割とカジュアルにリフレクションが使われたりします。まず静的解析で縛ることを考え、決定論的に書けないものはプロジェクト固有のガイドラインを書くなどしてください
  • 構造的な問題や落とし穴などの観点は人間によるコードレビューが必要です
  • コード品質は既存のコードベースに引っ張られます。既存プロジェクトに導入する場合は、まず /refine-tests スキルでテストコードをリファインすることをお勧めします

使用感・メトリクス

主に、Slay the Spireクローンの制作に使用したときのもの。

  • プルリクエストにするくらいの粒度で使用して、プラン承認後1〜2時間(最近遅いので)自走して、実装・テストを完了します
    • UIレイアウトは雑なものですが、ちゃんと操作できるものが出来上がります(他のGameObjectによってブロックされていないことなどもテスト済み)
    • バグは出ますが仕様定義の漏れが支配的で、仕様レビューを厳密にすることで防げるはず(本プラグイン対象外)
  • テストケースレビューだけで、コードレビューは(テストコードもプロダクトコードも)省略することがほとんど*2。テストケースレビューも全ケースではなく、統合テストや受け入れテスト*3を中心にレビューしています
  • 内部品質は十分とは言えませんが、Claude Codeで開発イテレーションを繰り返しても崩壊しない程度の品質はキープできています*4
  • ステートメントカバレッジは 97.5% *5
  • code : test ratio は 1 : 5.0 *6

参考

本プラグインのスキルがベースとしているテスト設計・実装、メトリクス、Roslynアナライザなどについて詳しくは、次の同人誌を参照してください。 テストケースをレビューする際の観点・判断基準や、スキルをカスタマイズする助けになるはずです。

www.nowsprinting.com

*1:スクリーンショットを撮るテストコードに検証観点を残しているので、目視検証を含めたリグレッションテストを指示すれば再実行も可能。将来的に初回パスしたら以降は正解画像との画像比較によるビジュアルリグレッションテストに変換する案もあり

*2:スキル改善のために見ることはあります

*3:まだ精度が低いのですが、要求に対応したテストに「受け入れテスト」マーカーがつきます

*4:仕事で書くライブラリなどのコードは、ここから温かみのある手作業でリファクタリングしています

*5:ゲームの特性と、I/Oや通信がなく例外処理がほぼないためカバレッジは高め

*6:AIはテストを書きすぎる傾向があるので、この code : test ratio を低く抑えることが直近の課題

Gameplay MCP Server for Unity を公開しました

Unity製ゲームのランタイムに組み込んでAIエージェントにゲームをプレイさせるためのMCPサーバパッケージを公開しました。 Unityエディタを操作するMCPサーバは多数公開されていますが、これは操作対象がゲーム本体で、エディタ内だけでなくプレイヤービルドでも動作するものです*1

基本的なツールの実装を終えた状態で、バージョンは 0.3.0 です*2

github.com

MCPサーバ部分には MCP C# SDK を採用、ゲームタイトルで自由にカスタムツールを追加できます。 uGUI要素の操作は DeNA/Anjin でも使用されている UI Test Helper を使用しており、GameObjectの出現を(固定時間でなく)ポーリングで待ったり、ユーザの操作をブロックするオブジェクトがあるときは操作できないと判断するなど、UIテストに必要な機能を備えています。また、ゲームタイトル固有のカスタムUIフレームワークにも対応できます。

ビルトインツール

ビルトインで提供しているツールは次の5つです。

list_available_actions

画面に表示されている操作可能な*3 GameObject と、可能な操作(クリック、ドラッグなど)の組み合わせを返します。 モデルはこの中から次のアクションを選択できます。

invoke_action

対象 GameObject と操作を指定して、操作を実行します。

inspect_game_object

GameObject を、name, path*4, text*5, texture*6 を指定して検索し、プロパティを取得します。 表示まで時間がかかる場合でも GameObject の出現を一定時間ポーリングして待ちます。 操作の結果、表示されるはずの GameObject を確認するのに使用できます。

take_screenshot

スクリーンショットを撮影して返します*7

list_scenes

ロードされているSceneを返します。簡易的なゲームの状態確認ツールです。

カスタムツールの実装

ゲームタイトル固有のカスタムツールを追加できます。たとえば次のような用途を想定しています。

  • 現在のゲームの状態を返す
  • uGUI以外の操作
  • デバッグコマンドの実行

カスタムツールは、次のように MCP C# SDK の [McpServerToolType] および [McpServerTool] 属性を配置することで認識されます。

// Assets/Scripts/Runtime/MyGameTools.cs (custom tools created by the game title)
// Just add [McpServerToolType] and it's registered automatically!
[McpServerToolType]
public class MyGameTools
{
    [McpServerTool(Name = "get_player_status", ReadOnly = true, Destructive = false)]
    [Description("Returns the player's current status as JSON.")]
    public async Task<string> GetPlayerStatus(CancellationToken ct = default)
    {
        await UniTask.SwitchToMainThread(ct);
        var player = GameObject.FindWithTag("Player");
        return JsonSerializer.Serialize(new { hp = player.GetComponent<Health>().Current });
    }
}

なお、たとえばゲームの状態を返すツールを実装したことによって list_scenes ツールが不要になったときは、次のように無効化できます。

var config = new McpConfig();
config.DisabledTools.Add("mygame.list_scenes");

使用方法

インストール

あらかじめ MCP C# SDK v1.0.0 以降をインストールします。 NuGetパッケージなので NuGetForUnity などを利用してください*8。NuGetForUnityの使いかたについては過去記事を参照してください。

www.nowsprinting.com

続いて Gameplay MCP Server for Unity パッケージをOpenUPMからインストールします*9

  1. Project Settings ウィンドウを Editor > Project Settings で開き、Package Manager タブを選択
  2. Scoped Registries 下の + ボタンをクリックして次のように入力します
    1. Name: package.openupm.com
    2. URL: https://package.openupm.com
    3. Scope(s): com.nowsprinting and com.cysharp
  3. Package Manager ウィンドウを Window > Package Manager で開き、My Registries タブを選択
  4. Gameplay MCP を選択して Install ボタンをクリック

MCPサーバの起動

MCPサーバは次のコードで起動できます。 [RuntimeInitializeOnLoad] 属性などでゲーム起動時に常に起動したり、デバッグメニューから起動するなどします。

var config = new McpConfig
{
    OperatorPool = new OperatorPool()
        .Register<UguiClickOperator>()
        .Register<UguiDragAndDropOperator>()
        .Register<UguiTextInputOperator>()
};
var server = new McpServer(config);
server.StartAsync().Forget();

McpConfigには使用するオペレーターのほか、GameObjectを探す GameObjectFinder、操作可能の判断に使用するストラテジ関数などを指定できます。 これらはUI Test Helperパッケージの機能なので、詳細はUI Test Helperのドキュメントを見てください。

なお、サーバの待ち受けポートは McpConfig のほか、コマンドライン引数でも指定できます。マルチプレイヤーでも安心。

AIエージェントの設定

次のように設定します。Claude Codeの例:

{
  "mcpServers": {
    "gameplay": {
      "type": "http",
      "url": "http://localhost:8010/mcp"
    }
  }
}

Agent Skills

MCPサーバだけでも操作手順を指示する形であれば動くはずですが、ゲームを自律的プレイさせるには、ゲームのルール、目的などをAgent Skillsとして与える必要があります。

また、uGUIの操作ができなかったときなどの問題の切り分けのために、UI Test Helperのトラブルシュート資料もスキル化しておくと役立つはずです。

今後の展望

あといくつかツールを追加*10するほか、UI Test Helperの Paginator 関連の機能追加などを予定しています。

*1:IL2CPPビルドでも動作しますが、仕組み上WebGLは対象外です

*2:中途半端ですが、なんとなく今週アナウンスしようという気持ちになたっため

*3:interactable=true かつ、カメラからレイキャストが通る(ほかのオブジェクトにブロックされていない)もの

*4:ヒエラルキーのパス

*5:ボタンなどの表示テキスト

*6:ボタンなどのテクスチャファイル名

*7:スクリーンショットは補助的な、結果確認用ツールの位置づけなのですが、エージェントは割と安易に使ってきます。無駄なトークン消費を抑えるためには、Agent Skillsで用途を限るように書くなどして抑制してください

*8:UnityNuGetには登録済みで、レジストラへの反映待ち

*9:git urlでもインストールできますが、その場合は依存パッケージを手動でインストールしてください

*10:persistentDataPathアクセスなどを予定

MCP Server Extension for Unity v1.0.0 リリース

Unity Editor 向けの新しい MCPサーバ、MCP Server Extension for Unity をリリースしました。 JetBrains Riderにインストールするプラグインで、RiderにビルトインされているMCP Serverにツールを追加する拡張機能です*1

特徴は次の3点です。

  • UnityプロジェクトへのUPMパッケージインストールなし*2で利用可能
  • ビルトインの MCP Server を設定済みであれば、追加設定なしで利用可能
  • 複製したワークスペース*3からの同時使用も追加設定なしで可能

提供するツールは次の4つ。MCP Serverは21のツールを提供していますが、それに+4されます。

  • run_unity_tests: Unity Test Runnerでテストを実行します
  • run_method_in_unity: 任意のstaticメソッドを実行します*4。このツールで、sceneおよびprefabファイルを編集できます
  • get_unity_compilation_result: アセットをリフレッシュし、コンパイル結果を取得します
  • unity_play_control: 再生モードを操作します

プラグインページはこちら。

plugins.jetbrains.com

リポジトリはこちら。

github.com

利用方法

プラグインのインストール

  1. Settings > Plugins を開く
  2. Marketplace タブで "mcp unity" などで検索
  3. Install をクリック

MCPサーバの設定

ビルトインの MCP Server を設定済みであれば、すぐ使えます。

未設定の場合は

  1. Settings > Tools > MCP Server を開く
  2. Enable MCP Server をクリック
  3. お使いのCoding Agentに応じた Auto-Configure をクリック

詳しくは MCP Server ドキュメントを参照してください。

Agent Skills

必須ではありませんが、テスト実行ツールで指定するテストモードやアセンブリ名の求め方を指示するAgent Skillを設定すると便利です。 リポジトリのREADMEにサンプルを掲載していますので、参考にしてください。

アーキテクチャ

JetBrains IDEs 2025.2以降でビルトインされているMCPサーバには、カスタムプラグインでツールを拡張できる仕組みがあります。 Coding Agentとのインタフェースはこれを利用しています。個別に設定する手間を省けるほか、複数ワークスペースからの同時使用も考慮されており、ツールの実装に集中できます。

Rider向けプラグインは、JetBrains IDEsプラグインとして振る舞うためのKotlinフロントエンド層と、C#バックエンド層の2レイヤ構成です。 本プラグインで提供しているツールは、RiderのUnityプラグインが備えている(開かれている)インタフェースを呼び出し、Unityプラグインを経由してUnity Editor側のRider Editorパッケージと通信し、Unity Editorを操作しています。

この構造のため、Rider Editorパッケージの機能の範囲でしかツールを提供できません。従って今後機能追加の予定はなく、バグフィックス中心のメンテナンスになります。 また近い将来、JetBrains公式で同じ機能が提供されるはずです。そうなれば、このプラグインの公開も終了するつもりです。IDEバージョンの追随がめんどくさいので早く手放したい(本音)。

所感

コードはほぼClaude Codeさんが書きました。メンテしない前提なので内部品質は気にしない、ということで、狭義のvibe coding寄りで。 でもテストは書かせているしテストケースをレビューしているので、vibe codingとは言えない。普段の自分からはだいぶ寄っているという程度です。

Plan modeでテスト設計させたスキル*5やPlanファイルもリポジトリに入れてあるので、雰囲気わかっていただけるかと。

関連記事

www.nowsprinting.com

www.nowsprinting.com

*1:従って、正しくは「MCPサーバ」そのものは提供していません

*2:ビルトインのRider Editorパッケージは使用します

*3:cp, git clone, git worktree, claude --worktree などによる

*4:引数なしのメソッドのみで、戻り値は受け取れません

*5:Unity向けの移植なのでだいぶ適当

Test Helper v1.4.0 : FLIPによるTexture2D比較子

Unity Test Frameworkによるテストを書くときに便利な Test Helper パッケージの v1.4.0 をリリースしました。 本バージョンでは、ビジュアルリグレッションテストなどに便利なカスタム比較子 FlipTexture2dEqualityComparer を追加しました。

github.com

FlipTexture2dEqualityComparer

FlipTexture2dEqualityComparer は、2つの Texture2D を制約モデルで検証するときに使用できる比較子(comparer)です。 次のように使用します。

[Test]
public async Task MyTestMethod()
{
  // テスト実行(省略)

  // スクリーンショットを撮影
  await Awaitable.EndOfFrameAsync();
  var actual = ScreenCapture.CaptureScreenshotAsTexture();

  // 期待する画像をロード
  var expected = AssetDatabase.LoadAssetAtPath<Texture2D>(ExpectedImagePath);

  // 比較子を使って検証
  var comparer = new FlipTexture2dEqualityComparer(meanErrorTolerance: 0.01f);
  Assert.That(actual, Is.EqualTo(expected).Using(comparer));
}

通常、オブジェクト同士を Is.EqualTo で比較すると参照の比較になりますが、Using モディファイアで比較子を渡すことで比較方法を指定できます。 FlipTexture2dEqualityComparer はFLIP(後述)を使用して2つの Texture2D を比較し、平均エラー値がしきい値(上例では 0.01f)より高ければテストを失敗させます。

また失敗時には、エラー値から生成したマップファイルを出力します。差異の大きいところが暖色になるマグママップ(ヒートマップ)です。

FlipBinding.CSharp

FlipTexture2dEqualityComparer を使用するには、Test Helperパッケージのほかに、FlipBinding.CSharp NuGetパッケージのインストールが必要です。

FlipBinding.CSharp は、FLIP(後述)の C#バインディングAPIで、株式会社サイバーエージェント SGEコア技術本部が公開しているOSSです。 Windows, macOS, Linuxで動作します。

www.nuget.org

FlipBinding.CSharp は、UnityNuGet(OpenUPM)もしくは NuGetForUnity からインストールできます。 UnityNuGet および NuGetForUnity の使いかたは次の記事を参照してください。

www.nowsprinting.com

なお、UnityNuGet(OpenUPM)以外 からインストールしたときは、カスタムスクリプティングシンボル ENABLE_FLIP_BINDING の設定も必要です。

FLIP

FLIP は、NVIDIA Research Projects が公開している画像比較アルゴリズムです。 Python および C++ 実装がOSSとして公開されています。

github.com

FLIP は人間の目が認識する差異を評価してくれるアルゴリズムで、従来手法のようにパラメタ調整に悩むことなく、しきい値の決定だけで精度の高いビジュアルリグレッションテストを運用できるのが特徴です。 FLIP によるビジュアルリグレッションテストについて詳しくは、次の清原氏によるブログ記事および CEDEC 2025 の講演資料が参考になります。

blog.sge-coretech.com

cedil.cesa.or.jp


Unity Test Framework によるテストについては同人誌を頒布していますので、こちらも参考にしてください。

ikagoya.booth.pm

ikagoya.booth.pm

UnityではRoslynアナライザーのどのバージョンを使えばいいのか

Unity 2020.2 からUnityエディターでRoslynアナライザー(およびソースジェネレーター)がサポートされましたが、Unityエディタに同梱されているMicrosoft.CodeAnalysis.CSharpのバージョンよりも新しいバージョンでコンパイルされたアナライザーは動作しません。

どのバージョンが動作するのか、過去記事などで紹介したものもありますが、できるだけ最新のバージョンを使いたいと考えると都度確認せざるを得ず、とても面倒です。 そこで、Unity の各バージョンに対してどのバージョンが使用できるかを網羅したリファレンスリポジトリを作りました。

github.com

アナライザーごとのUnityで動作するバージョン情報

たとえばIDisposableAnalyzersページを見ると、最新バージョンは4.0.8ですが、 Unity 2022.2以降ではv4.0.4、 Unity 2022.2未満ではv3.4.15 を使用しなければならないことがわかるようになっています。

Version Microsoft.CodeAnalysis.CSharp Unity 2020.2 Unity 2021.2 Unity 2022.2 Unity 6000.0
4.0.8 4.5.0.0
4.0.7 4.5.0.0
4.0.6 4.5.0.0
4.0.5 4.5.0.0
4.0.4 4.0.0.0
4.0.3 4.0.0.0
4.0.2 4.0.0.0
4.0.1 4.0.0.0
4.0.0 4.0.0.0
3.4.15 3.5.0.0

なお、Microsoft.CodeAnalysis.CSharp以外の依存はチェックしていませんのでご注意ください。 たとえばNUnit.Analyzersは最新のv4.11.2までUnity 2022.2以降で動作するように見えますが、v4系はNUnit 4が前提であり、Unity Test FrameworkではNUnit 3ベースのv3.9.0*1までしか使えません。

アナライザーの追加・更新

アナライザーの検証および表の生成はGitHub Actionsワークフローになっており、リポジトリに無いアナライザも次の手順で確認できます。

  1. リポジトリをフォークします
  2. フォークリポジトリGitHub Actions workflowを実行します
    1. リポジトリのページで Actions > Check Roslyn Analyzer Versions を開く
    2. Run workflow ドロップダウンをクリック
    3. NuGetのパッケージIDを入力 (e.g., Microsoft.Unity.Analyzers)
    4. Run workflow ボタンをクリック
  3. ワークフローが実行され、新しいブランチにMarkdownファイルがpushされます

ぜひ実行結果をプルリクエストで送ってください。

なお、一度アナライザのページを追加すると、定期的に自動更新されるようになっています。

UnityエディタのMicrosoft.CodeAnalysis.CSharpバージョン確認

Unityエディタに同梱されているMicrosoft.CodeAnalysis.CSharpバージョンを確認するツールを tools/check-unity-roslyn-version.ps1 に置いてあります。

実行結果(すべてのUnityバージョンではない)は docs/unity_roslyn_versions.md に残しています。

こちらはまだ手動実行ですが、そのうち自動化したいと思っています。

関連記事

UnityプロジェクトへのRoslynアナライザー導入方法は、同人誌および過去記事で紹介しています。

www.nowsprinting.com

www.nowsprinting.com

www.nowsprinting.com

www.nowsprinting.com

*1:v3.10.0からNUnit 4に依存

Unity Test Framework完全攻略ガイド 第3版

3年ぶりの改版となる『Unity Test Framework完全攻略ガイド 第3版』を、コミックマーケット107の2日目(水曜日)南i-17b「いか小屋」で頒布します。

第3版では、Unity Test Frameworkパッケージの最新APIへの追随だけでなく、本書で扱う範囲を広げています。 第1章は大幅にリライトし、ユニットテスト以外のテスト活動も含めた全体像や自動テストの保守性にも言及しています。 また追加した第14章「継続的インテグレーション」でCI環境の構築方法を解説しているほか、テストコードの保守・運用や実装テクニックについての一般知識も盛り込みました。

想定読者

UnityでC#スクリプトを書けるレベルのソフトウェアエンジニア(プログラマー)を想定しています。UnityやC#言語自体の解説はしていません。 テスト、特にユニットテストに関しては、入門レベルからカバーしています。

また読者の属する開発プロジェクトの規模を、個人から小規模と想定しています*1CEDECなどで発表されるエンドツーエンド(E2E)テストの自動化は難易度も高くコストもかかるものですが、開発者テストは個人や小規模チームでの開発でも効果を発揮します。むしろQA担当者の大量投入という選択肢のないプロジェクトでこそ有効活用すべき技術です。

目次の紹介

各章の内容(第2版からの差分)は次のとおりです。

第1章 テストとは何か

第2版から大幅にリライトしています。 「テスト」と、ゲーム業界で使われる「デバッグ」という言葉の違い、CEDEC2025のセッション『E2Eだけがテスト自動化じゃない! Unity製ゲームの開発者テスト チュートリアル』でお話したシフトレフト、階層化テスト戦略、また自動テストの保守性にも言及しています。

第2章 Unity Test Frameworkの基本

Unity Test Frameworkパッケージを使ってユニットテストを書き、実行する手順を、順序立てて説明しています。 第3版では「2.6 よいテストコードを書くヒント」を追加しています。

第3章 テストモード

Edit ModeテストとPlay Modeテストの違い、それぞれに固有のAPIを紹介しています。 第2版までは個別の章でしたが統合しました*2

第4章 非同期処理のテスト

第3版ではUnity Test Framework v1.3でサポートされたasync/awaitによる非同期テストを追加し、従来からあるUnityTest属性によるテストについても制限事項をアップデートしています。

第5章 アサーション

NUnit3の制約モデル(Assert.That)によるアサーション(テスト実行結果の検証)について、検証対象や目的に応じた最適な書きかたやTips、アンチパターンを紹介しています。

第3版では、制約モデルの記述例および失敗メッセージ例をいくつか本文中に記述するようにしました。 またTipsに分散していた特殊なアサーションに関する記述を本章にまとめました。

第6章 パラメタライズドテスト

ひとつのメソッドを引数を様々に変えてテストしたいときに使用できるパラメタライズドテストの使いかたを紹介しています。

第3版では、Unity Test Framework v1.4で追加されたParametrizedIgnore属性および、Unity Test Frameworkの問題が解消されたTestFixture属性によるパラメタライズドテストについての解説を追加しました。

第7章 テストダブル

テスト対象が何らかのコンポーネントに依存しているとき(内部で生成した疑似乱数やサーバからのレスポンスに応じて結果が変わるなど)、その依存コンポーネントを偽物(スタブ、スパイ、モックなど)に置き換えてテストするテクニックを紹介しています。

第8章 Unity Test Framework Tips

テストの前処理・後処理、実行プラットフォーム制限、カテゴライズ、タイムアウト時間の変更、MonoBehaviourのテスト方法などを紹介しています。

第9章 Scene・アセット・ファイルの使用

Edit Modeテスト・Play Modeテスト(エディター実行)・Play Modeテスト(プレイヤー実行)それぞれで、Sceneファイルをロードしてテストに使用する方法を紹介しています。

第3版では、Scene以外のテスト用アセットをプレイヤー実行で使う方法などを追加しています。

第10章 UPMパッケージのテスト

Unity Package manager(UPM)パッケージのテストを実装・実行する方法紹介しています。

第11章 Unity Test Frameworkの拡張

第3版で追加した章です。 NUnitの属性、制約、比較子(Comparer)をゲームタイトルで拡張して使用する方法を紹介しています。

第12章 テストの実行方法

UnityエディターのTest Runnerウィンドウ、Jet Brains Rider、コマンドラインからのテスト実行方法・オプションを紹介しています。

第13章 コードカバレッジ

Unity Code Coverageパッケージを用いてコードカバレッジ(テストがプロダクトコードのどの部分をカバーしているかの指標)を採取する方法を紹介しています。

第14章 継続的インテグレーション

第3版で追加した章です。 GitHub Actionsを用いたCI環境の構築方法、octocovによるコードカバレッジの可視化などを紹介しています。

第15章 テスト実装のヒント

壊れやすい「実装のテスト」ではなく、変更に強い「仕様のテスト」を書くためのアプローチを紹介しています。 テストケースを導出するためのテスト技法(同値分割法・境界値分析・デシジョンテーブル・組み合わせテスト)、再現テスト、テスト駆動開発(TDD)。

第3版ではランダム性をもつテスト対象をどうテストするかのアプローチを追加しています。

付録A Test Helperパッケージ

第3版で追加した付録です。 筆者の公開しているUnity Test Framework拡張集であるTest Helperパッケージを紹介しています。

付録B Roslynアナライザー

第3版で追加した付録です。 Roslynアナライザーによる静的解析について紹介しています。

付録C JetBrains Rider Tips

IDEにRiderを使う場合の、コグニティブ複雑度の計測(CognitiveComplexityプラグイン)、テスト用Live Templateの紹介。

付録D OpenUPM-CLI

本書で紹介しているUPMパッケージをUnityプロジェクトにインポートするのに便利なopenupm-cliコマンドの紹介。

表紙

いかの足が2本から3本に!

スペックと頒布価格

変更点を特記していない章も、前提バージョンの変更や記述の見直しなどを実施しています。 原稿の行ベースで見ると第2版の4,623行に対して、+5,296行、-2,612行、差し引き(純増)+2,684行、計7,307行。 ページ数は152から220と68ページ増。

しかしなんと、お値段据え置き ¥2,000 で頒布します。たぶん増刷はしません。 当日残ればBOOTHで通販します。

また電子版はこれまで同様、第2版以前を購入いただいていれば追ってアップデートします。

スペースの場所

2日目(水曜日)南i-17b「いか小屋」です。

既刊の在庫も持っていきます。

www.nowsprinting.com

www.nowsprinting.com

関連

www.nowsprinting.com

www.nowsprinting.com

*1:ユニットテストを書くにあたって規模は関係ないのですが、CI環境としてGitHub Actionsを紹介しているあたりが小規模を意識しています

*2:単に目次の都合で大きな意味はありません