Unity Test Frameworkパッケージのバージョン1.3では、マニュアルの中にUnity Test Framework learning materialsというドキュメントが追加され、またそのサンプルコードがパッケージのSamplesに含まれるようになりました。
ドキュメントは、Unity Test Frameworkの基本的な使いかたを紹介するGeneral Introductionと、サンプルプロジェクトを題材にゲームの操作を伴うテストを書くTesting Lost Cryptで構成されています。
以下、それぞれ紹介します。
General Introduction
Unity Test Frameworkの基本的な使いかた(ユニットテスト中心)を紹介しています。
サンプルコードはUnity Test Framework v1.3.0のSamplesにあるのですが、恐らくパッケージの設定に不備がありPackage Managerウィンドウからインポートすることができません*1 *2。
サンプルコードを見たいのであれば、Unity Test Frameworkをv1.3.0にアップグレードし、
Library/PackageCache/com.unity.test-framework@1.3.0/Samples~/
にあるファイルを直接見るしかなさそうです。
サンプルは、例えば1_RunningTest_Project
がExercise1のテスト対象のみ、模範解答的テストを書いたものが1_RunningTest_Project_Solution
にあるという形式です。
なお、Exercise間で同じ名前のアセンブリを定義しているため、そのままでは同時に1つのSampleしかインポートできません*3。
インポートしたらasmdefファイル内のアセンブリ名を変えていくとよいでしょう。
以下、各Exerciseの内容です。
- Running Tests: 最初のテストを書いて実行するもの。テスト対象にバグがあって修正するというものなので、テスト初心者の方は
1_RunningTest_Project
から見ることをおすすめします - Arrange, Act, Assert: 読みやすいテストの書きかたとして3Aを紹介*4
- Semantic Test Assertion: NUnit3の制約モデルでのアサーションの書きかた、
Does.Contain().And.Contain()
といった表現力を紹介 - Custom Comparison: Unity Test FrameworkのEqualityComparerで許容誤差ありの比較
- Asserting Logs:
LogAssert.Expect
によるログ出力の検証 - Set Up and Tear Down: テストメソッドの前後に処理を行なう方法*5
- PlayMode Tests: 再生モードでテスト実行する方法
- PlayMode Tests in Player: スタンドアロンプレイヤーでPlay Modeテストを実行する方法
- UnityTest Attribute:
UnityTest
属性による複数フレームにまたがるテストの例*6 - Long Running Tests: 実行に時間がかかるテストに
Category
属性およびExplicit
属性を指定して実行タイミングをコントロールする方法 - Scene Based Tests: Edit ModeテストでSceneファイルをロードしてScene内のGameObjectを検証する方法*7
- Build Setup and Cleanup: テストのビルド前後に処理をはさむ
IPrebuildSetup
およびIPostBuildCleanup
の使いかた。テスト対象のSceneがプロジェクトのScenes in Buildに無いときに追加している*8 - Domain Reload: Edit Modeテストでスクリプトコンパイルなどドメインリロードを挟むテストの書きかた*9
- Preserve Test State: ドメインリロードが発生するテストでは変数が失われるので、回避策としてSerializeField属性を使う例*10
- Test Cases:
TestCase
属性によるパラメタライズドテストの書きかた。本文ではTestCaseSource
属性・Values
属性・ValueSource
属性にも触れられています - Custom Attributes: NUnitのカスタム属性を定義する例*11
- Runnings Tests Programmatically: TestRunnerApiの使用例。Sceneのバリデーションをテストとして実装し、それをメニューから呼ぶサンプル
Exercise16を除けば拙書『Unity Test Framework完全攻略ガイド』でも解説している内容です。日本語でより詳しい解説がほしい方はぜひ購入を検討してください。
Testing Lost Crypt
2Dゲームサンプル『Lost Crypt』を題材とした統合テスト(ユニットテストより結合度の高いテスト)の書きかたです。 こちらはSamplesにファイルはありません。
以下、内容と補足説明です。
Setting up
題材となるLost Cryptプロジェクト(無料)のセットアップを行います。
Running a test in LostCrypt
Sceneをロードして、GameObject "FX - Day"が存在することを確認するテストを追加します。
Moving character
テストコードからキャラクターを操作する仕組みを実装します(まだテストではない)。
Lost CryptはNew Input Systemパッケージ(UnityEngine.InputSystem
名前空間)を使用していますが、New Input SystemのInputAction
(抽象化層)は使用しておらず、低レベルAPIを使用して独自の抽象化層(CharacterController2D
クラス)を実装しています。
そのため、テストの実装方式は旧Input Managerでも近い形式で実装できるものになっています。
New Input SystemのInputAction
を使用しているのであれば、New Input SystemパッケージのマニュアルにあるInput testingが参考になるでしょう*12。
Reach wand test
キャラクター操作の延長で、Scene右端にあるワンドにたどり着くテスト。 たどり着くかはキャラクターの座標で判定、規定時間を過ぎたらタイムアウト*13で失敗するテストを書きます。
Collision test
コリジョン抜けのテスト。 実際にコリジョン抜けバグがあるのが草。
Asset change test
操作(ワンドまでたどり着く)によってアセットの変化(SpriteLibrary
のnameが切り替わること)を検証するテスト。
Scene validation test
Scenes in Buildに指定されている各Sceneに対して、SaraとWandが存在することを検証するパラメタライズドテストの例。
Performance tests
Performance Testingパッケージを使用して、fpsを計測・検証する例。
まとめ
こういったコンテンツが公式から出てくることはとても良いですね!*14
これを機にUnityのテストについて詳しく知りたい! という方は、ぜひ拙著『Unity Test Framework完全攻略ガイド』を読んでみてください*15。
また、統合テストにはAutomated QAパッケージも有用です*16。こちらも拙著『Unity Automated QA攻略ガイド』を参考にしてください。
*1:いくつかのUnityバージョンでダメでした。そうゆうとこやぞ…
*2:v1.3.2で修正されました。see: https://unity3d.atlassian.net/servicedesk/customer/portal/2/IN-23368
*3:ほんとそうゆうとこ…
*4:拙書『Unity Test Framework完全攻略ガイド』ではTeardownを加えた「4フェーズテスト」を紹介しています。ほぼ同じものです
*5:ファイル削除はTearDownでなくSetUpで行なうべきです。例として仕方ないところなのですが
*6:SamplesにはInitTestScene637147869846377210.unityというファイルが含まれているのですが、これはPlay Modeテスト実行時に自動生成されるSceneなので不要です
*7:これもTearDownでEditorSceneManager.NewSceneしているのはよくない。SetUpでやるべき
*8:拙書『Unity Test Framework完全攻略ガイド』ではITestPlayerBuildModifierで行なう方法を紹介しています
*9:SamplesのコードはパスのセパレータがWindowsのもの(\)になっています。ほかのOSの場合は修正要
*10:ドメインリロードでは(OneTimeSetUpやSetUpは再実行されるけど)UnitySetUpは再実行されないことが前提知識なのですが、書かれていない
*11:ただし例として書かれているものはMaxTime属性で実現できるものだし、使用しているIWrapTestMethodは非同期テストに使用できない属性なので、よい例とは思えない
*12:こちらもいくつかツッコミどころがあるのですが、それはまた稿を改めて
*13:Timeout属性に触れられていないのですがyield return nullではタムアウトが機能しなかったりテストがフリーズしたりします
*14:質はともかく、と言いたいところなのですが、品質関係のコンテンツの品質が低いのはちょっとよくないなと思うのです…
*15:Amazon Kindle版・ペーパーバック版も進めています。今しばらくお待ち下さい
*16:開発停止中ですが、Unity Test Framework v1.3で非同期テストも実装されたので、そろそろ開発再開されることを期待しています