これはなに?
SceneTestFixtureの簡単なコーディングメモ
背景
- プロトタイピングをしたいが、UIを作っていちいち動作させるのがめんどくさすぎた。
- TestRunnerを使ってプロトタイピングしたくなった。
- けれど、ライブラリのセットアップなどをテストコードでするのはめんどくさすぎたので、Scene上にライブラリだけ動作する環境を作って、テストコードから色々試したかった。
- ZenjectIntegrationTestFixtureでSceneをLoadしたが、そのままではITickableが動作しなかったりと色々不都合があった。
- SceneTestFixtureでLoadSceneを行ったところ正常動作したが、コーディングに色々試行錯誤したためメモを残すことにした。
気をつけること
テストのAssemblyはターゲットのプラットフォームを選択する(ex.MobileならiOS,Androidなど)
これやらないとTestRunnerのPlayModeのところにテストケースが載りません。
テストするシーンをBuildSettingに追加しておく
そりゃそうじゃ
テストクラスはSceneTestFixtureを継承する
ITickableとかちゃんと動いてくれる
各テストメソッドでyield return LoadScene("SceneName");する
[SetUp]とかでやるとうまく動かない。なぜかはまだ考えないことにした。
SceneContextはLoadSceneの記述のあとでDIする
シーン立ち上げないとSceneContextがそもそも無い
実装例
このように、シーン内で定義したDIContainerにテストコードからアクセスできる。
結果、色々はかどる。
// IAAAに準拠するAAAImplクラス
public class AAAImpl : IAAA{
}
/*
IAAAに依存しているBBBImplクラス
IBBBに準拠する
*/
public class BBBImpl : IBBB {
readonly IAAA aaa;
[Inject]
public Hoge ( IAAA aaa){
this.aaa = aaa;
}
}
/// シーン(SceneName.scene)内でSceneContextで呼び出されてるInstaller
public class Fuga : MonoInstaller {
/// IAAAにAAAImplを注入しちゃうぞ
Container.Bind<IAAA>().To<AAAImpl>().AsCached();
}
/// TestAssemblyの中に作成したシーンテスト用クラス
public class Hoge : SceneTestFixture {
[UnityTest]
public IEnumerator 依存解決できるか(){
yield return LoadScene("SceneName");
/// IBBBにBBBImplを注入
SceneContainer.Bind<IBBB>().To<BBBImpl>().AsCached();
/// 依存性の解決
/// シーン内で定義したIAAAの依存も解決して、AAAImplが注入されたBBBImplが誕生する。ハッピーバースデー
var b = SceneContainer.Resolve<IBBB>();
/// 依存解決できてるかテスト
Assert.IsNotNull(b , "bの依存性解決に失敗した");
}
}