やらなイカ?

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

Monkey Test Helper パッケージのトラブルシュート

Unity上でオブジェクトベースのモンキーテストを実行できる Monkey Test Helper パッケージ*1のトラブルシュート資料を和訳しました。 対応バージョンは 0.14.0 です。

Monkey Test Helper は、オートパイロットフレームワーク AnjinUGUIMonkeyAgent の内部実装にも使われています。

Monkey

TimeoutExceptionがスローされた

次のメッセージを伴なう TimeoutException がスローされたとき、操作可能な GameObject がSceneに1つもない状態が5秒間続いたことを示します。

Interactive component not found in 5 seconds

デフォルト実装では*2、次の要件をすべて満たす GameObject が1つもないことを示します。

  • Selectable を継承かつ interactable プロパティが true であるか、EventTrigger か、IEventSystemHandler インタフェースを実装したコンポーネント
  • IgnoreAnnotation コンポーネントがアタッチされていないこと
  • Camera.main からピボット座標へのレイキャストが通ること(ほかのオブジェクトで隠されていないこと)

どの条件で対象外とされたかを知るには、バーボーズログ(後述)を有効にします。

なお、タイムアウトまでの秒数は、 MonkeyConfig.SecondsToErrorForNoInteractiveComponent で指定できます。 この機能を無効にするには 0 を指定します。

InfiniteLoopExceptionがスローされた

次のメッセージを伴なう InfiniteLoopException がスローされたとき、指定されたバッファ長内で繰り返し操作が検出されたことを示します。

Found loop in the operation sequence: [44030, 43938, 44010, 44030, 43938, 44010, 44030, 43938, 44010, 44030]

上記メッセージでは、パターン [44030, 43938, 44010] がループしています。 数字は、操作された GameObjectインスタンス ID です。

検出可能な繰り返しパターンの最大長は、バッファ長の半分です。 バッファ長は MonkeyConfig.BufferLengthForDetectLooping で指定できます。 この機能を無効にするには 0 を指定します。

この例外は、Monkey Test Helper v0.15.0で追加されました。Anjinには v1.9で反映予定です。[3/8追記]

操作ログ

UGUIClickOperator operates to StartButton (UGUIMonkeyAgent01_0001.png)

このログは、オペレーター UGUIClickOperator が、StartButton という名前の GameObject を操作する直前に出力されます。 "UGUIMonkeyAgent01_0001.png" は、操作直前のスクリーンショットのファイル名です。

スクリーンショットは、MonkeyConfigScreenshots を設定すると撮影されます。

バーボーズログ

詳細なログは、MonkeyConfigVerbose に true を設定すると出力されます。

抽選対象
Lottery entries: [
  StartButton(30502):Button:UGUIClickOperator,
  StartButton(30502):Button:UGUIClickAndHoldOperator,
  MenuButton(30668):Button:UGUIClickOperator,
  MenuButton(30668):Button:UGUIClickAndHoldOperator
]

各エントリのフォーマットは「GameObject 名(インスタンスID):コンポーネントの型:オペレーターの型」です。

このメッセージは、Monkeyが操作するオブジェクトおよびオペレーターの抽選対象をすべて出力しています。 uGUI 互換コンポーネントかつ interactable プロパティが true であるものです。 この段階では IsIgnore および IsReachable による判定は行われていません。

なお、この時点で抽選対象となるオブジェクトがひとつもないときは、次のメッセージが出力されます。

No lottery entries.
無視されたGameObject

抽選した GameObject が無視するように指定されたもの(デフォルトでは IgnoreAnnotation コンポーネントがアタッチされたもの)であったとき、次のメッセージを出力して再抽選されます。

Ignored QuitButton(30388).
ユーザーが到達不可能なGameObject

抽選した GameObject がユーザー到達不可能(デフォルトでは Camera.main からピボット座標へのレイキャストが通らないもの)であったとき、次のメッセージを出力して再抽選されます。

Not reachable to CloseButton(-2278), position=(515,-32). Raycast is not hit.

もしくは

Not reachable to BehindButton(-2324), position=(320,240). Raycast hit other objects: [BlockScreen, FrontButton]

前者は画面外など、後者はほかのオブジェクトによってピボット座標が隠されている状態です。 レイキャストを送る座標は ScreenOffsetAnnotation などのアノテーションコンポーネントでアレンジできます。

操作可能なGameObjectがひとつもない

操作可能なGameObjectがひとつもなかったとき、次のメッセージが出力されます。 この状態が一定時間続くと TimeoutException がスローされます。

Lottery entries are empty or all of not reachable.

GameObjectFinder

TimeoutExceptionがスローされた

名前が一致するものが見つからない

指定された名前を持つ GameObject が見つからなかったとき、次のメッセージを伴なう TimeoutException がスローされます。

GameObject `Target` is not found.
パス不一致

指定された名前を持つ GameObject のパス(Sceneのヒエラルキー)が一致しないとき、次のメッセージを伴なう TimeoutException がスローされます。

この判定は FindByPathAsync メソッドでのみ行われます。

GameObject `Target` is found, but it does not match path `Path/To/Target`.
ユーザー到達不可能

指定された名前を持つ GameObject がユーザー到達不可能(デフォルトでは Camera.main からピボット座標へのレイキャストが通らないもの)であったとき、次のメッセージを伴なう TimeoutException がスローされます。

この判定を行なうか否かは FindByNameAsync および FindByPathAsync の引数 reachable で指定できます。デフォルトは true(判定する)です。

GameObject `Target` is found, but not reachable.

詳細なログが必要な場合は、ILogger インスタンスGameObjectFinderコンストラクターに渡してください。

操作不可能

指定された名前を持つ GameObject が操作不可能(uGUI 互換コンポーネントでない、もしくは interactable プロパティが false)であったとき、次のメッセージを伴なう TimeoutException がスローされます。

この判定を行なうか否かは FindByNameAsync および FindByPathAsync の引数 interactable で指定できます。デフォルトは false(判定しない)です。

GameObject `Target` is found, but not interactable.

関連

www.nowsprinting.com

www.nowsprinting.com

www.nowsprinting.com

www.nowsprinting.com

*1:近い将来、UI Test Helper に改名予定です

*2:ストラテジパターンを採っているので、カスタムUIフレームワークを使っているタイトルでは判定関数を挿し替えできます