Unity Test Framework でUIを操作するテストを書くときに便利なライブラリ UI Test Helper パッケージのバージョン 1.0.0 をリリースしました。
元々モンキーテスト用のライブラリ(旧称 Monkey Test Helper)として開発していましたが、モンキーに限らずUIテストに使えるAPIが増えてきたので改名しました*1。
インストールは、GitHubリポジトリ指定や、openupm.comから可能です。 openupm-cli であれば次のコマンドでインストールできます。
openupm add com.nowsprinting.test-helper.ui
以下、v1.0.0で実装している機能を簡単に紹介します*2。
TOC
GameObjectの検索
GameObjectFinderクラスでScene上のGameObjectを検索できます。GameObject.Findと異なる次のような特徴があります。
- GameObjectが見つからない場合、指定したタイムアウトまでポーリング*3
- ユーザーが到達可能(カメラからのレイキャストが通ること)を条件にできる*4
- 操作可能な状態を条件にできる*5
- GameObjectのパスで検索するとき、globのワイルドカード書式が使用できる
Buttonを text および textureファイル名で検索できる(ButtonMatcherを使用)- カルーセルやスクロール領域内のオブジェクトも検索できる(uGUIの
ScrollRectであればUguiScrollRectPaginatorを使用)
使用例
using NUnit.Framework; using TestHelper.UI; [TestFixture] public class MyIntegrationTest { [Test] public async Task パスで検索() { var finder = new GameObjectFinder(5d); // 5 seconds timeout var result = await finder.FindByPathAsync("/**/Confirm/**/Cancel", reachable: true, interactable: true); var cancelButton = result.GameObject; } [Test] public async Task ボタンのテキストで検索() { var finder = new GameObjectFinder(); var matcher = new ButtonMatcher(text: "Click Me"); var result = await finder.FindByMatcherAsync(matcher, reachable: true, interactable: false); var button = result.GameObject; } [Test] public async Task ScrollRect内のボタンを検索() { var finder = new GameObjectFinder(); var matcher = new NameMatcher("Button_10"); var scrollView = GameObject.Find("Scroll View"); var scrollRect = scrollView.GetComponent<ScrollRect>(); var paginator = new UguiScrollRectPaginator(scrollRect); var result = await finder.FindByMatcherAsync(matcher, paginator: paginator); var button = result.GameObject; } }
GameObjectの操作
操作に応じたオペレーターが定義・実装されており、uGUIのイベントシステムを使用してクリックなどのイベントをGameObjectに送って操作します。
たとえば UguiClickOperator であれば、次のイベントを再現します。
OnPointerEnterOnSelect*6OnPointerDownOnInitializePotentialDragOnPointerUpOnPointerClickOnPointerExit
使用例
using NUnit.Framework; using TestHelper.UI; [TestFixture] public class MyIntegrationTest { [Test] public async Task InputFieldに文字入力してSubmitButtonをクリック() { var finder = new GameObjectFinder(); var message = await finder.FindByNameAsync("Message", interactable: true); var inputOperator = new UguiTextInputOperator(); await inputOperator.OperateAsync(message.GameObject, "Hello, Hurry?"); var submit = await finder.FindByNameAsync("SubmitButton", interactable: true); var clickOperator = new UguiClickOperator(); await clickOperator.OperateAsync(submit.GameObject); } }
モンキーテスト
画面上の操作可能なUI要素をでたらめに操作します。
テスト実行時間や操作間隔、また使用する操作の種類は MonkeyConfig で指定できます。
なお、モンキーテストで操作させたくないUI要素を無視させる IgnoreAnnotation のほか、操作する座標をずらしたり入力する文字種類の指定を行うアノテーションコンポーネントを利用できます。
使用例
using System; using System.Threading.Tasks; using NUnit.Framework; using TestHelper.UI; [TestFixture] public class MyIntegrationTest { [Test] public async Task モンキーテスト() { var config = new MonkeyConfig { Lifetime = TimeSpan.FromMinutes(2), DelayMillis = 200, SecondsToErrorForNoInteractiveComponent = 5, }; await Monkey.Run(config); } }
エディター拡張
パスのコピー
ヒエラルキーウィンドウでGameObjectを右クリックして Copy to Clipboard > Hierarchy Path でGameObjectのパスをクリップボードにコピーできます。
インスタンスIDのコピー
ヒエラルキーウィンドウでGameObjectを右クリックして Copy to Clipboard > Instance ID でGameObjectのインスタンスIDをクリップボードにコピーできます。
カスタムUIフレームワークへの対応
uGUIに準拠していないカスタムUIフレームワークを使用している場合、ビルトイン機能をそのまま使用できない場合があります。 UI Test Helperは次の拡張ポイントを用意しており、必要に応じてゲームタイトル側に実装することで紹介したAPI(モンキーテストも含め)をそのまま利用できます。
- オブジェクトが操作可能かを判断する関数
- オブジェクトを無視するべきかを判断する関数
- ユーザーがオブジェクトに到達可能かを判断する関数
- 検索に使用するMatcherの実装
- 検索に使用するPaginatorの実装
- Operatorの実装