Unity Test Frameworkによるテストを書くときに便利な Test Helper パッケージの v1.6 をリリースしました。 本バージョンでは、UIレイアウトを検証するための4つのカスタム制約(constraint)を追加しています。
UIレイアウトは変更される可能性が高いため、テストを書く投資対効果(ROI)が低く「書くべきでない」領域でした。 しかし、昨今、AIコーディングエージェントにsceneやprefabを編集させるようになると、人間では起こさないようなミス(コンポーネントの重なり、はみ出しなど)が発生します。 これを自律的かつ低コストで修正させるため、最低限の検証を機械的に行うために使用します。
WithinScreen制約
WithinScreen制約は、モーダルダイアログなどのUI要素が画面内に表示されている(はみ出ていない)ことを検証します。
次のように使用します。
using Is = TestHelper.Constraints.Is; [TestFixture] public class MyTestClass { [Test] public void MyTestMethod() { var confirmDialog = GameObject.Find("ConfirmDialog"); Assert.That(confirmDialog, Is.WithinScreen); } }
失敗した場合は、次のように具体的なメッセージが出力され、コーディングエージェントに修正を促します。
Expected: RectTransform within screen (0, 0, 640, 480) But was: "ConfirmDialog" (-12.0, 437.0, 50.0, 50.0) exceeds the left edge by 12.0px and the top edge by 7.0px
なお、検証したいUI要素が複数あるときは、AllオペレーターでAssert.That(elements, Is.All.WithinScreen);と書けます。
また、修飾子.Within(float)で許容誤差を指定できます。デフォルトは 0.5f です。
WithinContainer制約
WithinContainer制約は、UI要素がダイアログなどのコンテナ要素内に表示されている(はみ出ていない)ことを検証します。
次のように使用します。
using Is = TestHelper.Constraints.Is; [TestFixture] public class MyTestClass { [Test] public void MyTestMethod() { var viewport = GameObject.Find("Viewport").GetComponent<RectTransform>(); var card = GameObject.Find("Card (0)"); Assert.That(card, Is.WithinContainer(viewport)); } }
修飾子.Horizontally()もしくは.Vertically()で、横方向・縦方向のみ検証できます。
また、.Within(float)で許容誤差を指定できます。デフォルトは 0.5f です。
Overlapping制約
Overlapping制約は、UI要素同士の重なりを検証します。
次のようにNotオペレーターで「重なっていない」ことを検証できます。
using Is = TestHelper.Constraints.Is; [TestFixture] public class MyTestClass { [Test] public void MyTestMethod() { var cards = GameObject.Find("CardGrid").GetComponentsInChildren<Image>(); Assert.That(cards, Is.Not.Overlapping); } }
修飾子.Ignoring(group)で、group間の重なりを検証から除外できます。
また、.Within(float)で許容誤差を指定できます。デフォルトは 0.5f です。
TextOverflowing制約
TextOverflowing制約は、TextおよびTMP_Textのテキストのはみ出し/切り詰めを検証します。
次のようにNotオペレーターで「はみ出し/切り詰めされていない」ことを検証できます。
using Is = TestHelper.Constraints.Is; [TestFixture] public class MyTestClass { [Test] public void MyTestMethod() { var flavorText = GameObject.Find("Flavor Text"); Assert.That(flavorText, Is.Not.TextOverflowing); } }
また、修飾子.Within(float)で許容誤差を指定できます。デフォルトは 0.5f です。
補足:アサーションでやらないこと
今回追加した制約で検証するのは、恒久的に変更されないであろう(テストが壊れにくいであろう)観点のみです。
このほか、たとえばCanvasScalerの設定などプロジェクトでルールがあるものは、scene/ prefabのバリデーションを行なうテストを書くとよいでしょう。
筆者が公開しているunity-coding-skillsでは、機械的なアサーションをパスした後、コンポーネントの位置関係、色(コントラスト)、タイポグラフィなどの観点について、画像認識で検証させています*1。
参考
カスタム制約、scene/ prefabのバリデーション方法などは、こちらで解説しています。
*1:CIなどで毎回実行するのではなく、セッション内で変更があったときのみ実行


