Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Zenjectとテスト
いも
March 20, 2018
Programming
0
7.1k
Zenjectとテスト
Gotanda.unity #5で発表するやつです
いも
March 20, 2018
Tweet
Share
More Decks by いも
See All by いも
Unityテスト活動のふりかえり
adarapata
1
260
Gather.townはいいぞ その後
adarapata
1
740
Unityでの開発事例
adarapata
4
17k
どこのご家庭にもあるシーンマネージャーの話
adarapata
1
2k
Gather.townはいいぞ
adarapata
2
1.9k
宴はいいぞ
adarapata
0
820
わかった気になるモブプログラミング
adarapata
1
25
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
970
Zenjectを導入する前に
adarapata
0
3.2k
Other Decks in Programming
See All in Programming
Voiceflowではじめる音声アプリ・チャットボット開発〜2022年版〜 / Introduction to Developing Voice Apps & Chatbots with Voiceflow
kun432
0
170
ISUCON12 事前講習
rosylilly
3
3.8k
Mobile Product Engineering
championswimmer
0
290
I/O Extended 2022 in Android ~ Whats new in Android development tools
pluu
0
520
Cross Deviceチームにおけるスマートテレビアプリ開発ってどんな感じ?
cokaholic
0
120
実践エクストリームプログラミング / Extreme Programming in Practice
enk
1
350
1時間半で克服するJavaScriptの非同期処理/async_javascript_kokufuku
marchin1989
2
590
How we run a Realtime Puzzle Fighting Game on AWS Serverless
falken
0
240
個人開発でReact Native + Expo製アプリを作った話
ryonakae
1
440
Terraform Plan/Apply結果の自動通知
ymmy02
0
270
はじめてのプルリク - BLEA 編
watany
0
140
IE Graduation (IE の功績を讃える)
jxck
20
12k
Featured
See All Featured
Pencils Down: Stop Designing & Start Developing
hursman
112
9.8k
No one is an island. Learnings from fostering a developers community.
thoeni
9
1.1k
Docker and Python
trallard
27
1.6k
GraphQLの誤解/rethinking-graphql
sonatard
27
6.5k
Designing with Data
zakiwarfel
91
3.9k
Agile that works and the tools we love
rasmusluckow
319
19k
Mobile First: as difficult as doing things right
swwweet
213
7.5k
How to Ace a Technical Interview
jacobian
265
21k
How To Stay Up To Date on Web Technology
chriscoyier
780
250k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
7
1.1k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
151
13k
Embracing the Ebb and Flow
colly
73
3.4k
Transcript
Zenject でのテスト Gotanda.unity #5 2018/03/20
自己紹介 いも(@adarapata) ミクシィ XFRAG ゲー ムプログラマ 入社三日目 最近GodotEngine が楽しい
今日の内容 Unity 標準のテストの書き方と、Zenject を使って いる場合のテストの書き方の違いを知る。 ※ Unity 内でのテストコー ドが必要かどうかについて は今回は話しません。
Zenject is https://github.com/modesttree/Zenject Unity で使えるDI フレー ムワー ク 依存関係をすっきりさせてくれる かせさんの記事がわかりやすい
http://yutakaseda3216.hatenablog.com/entry/201 7/04/17/124612
Unity のTest 書いてますか?
Unity でのテスト方法 EditModeTest エディタ上で動くテスト PlayModeTest シー ン上で動作確認できるテスト
Zenject in Unity でのテスト方 法 EditModeTest == Zenject Unit Test
エディタ上で動くテスト PlayModeTest == Zenject Integration Test シー ン上で動作確認できるテスト
Foo がIBar に依存してる処理( 通常) public class Foo { public IBar
bar; public int CallBar() // このメソッドをテストしたい { return bar.Bar() * 2; } } public interface IBar { int Bar(); }
EditModeTest public class FooEditModeTest { class MockBar : IBar {
public int Bar() { return 5; } } [Test] public void CallBarTest() { Foo foo = new Foo { bar = new MockBar() }; Assert.AreEqual(10, foo.CallBar()); } } Foo に流し込むモック用クラスを作る必要がある
Foo がIBar に依存してる処理 (Zenject) public class Foo { [Inject] public
IBar bar { get; private set; } public int CallBar() // このメソッドをテストしたい { return bar.Bar() * 2; } } public interface IBar { int Bar(); }
[TestFixture] public class FooUnitTest : ZenjectUnitTestFixture { [Test] public void
CallBarTest() { var mock = new Mock<IBar>(); mock.Setup(b => b.Bar()).Returns(5); Container.BindInstance(mock.Object); Container.Bind<Foo>().FromNew().AsSingle(); var foo = Container.Resolve<Foo>(); Assert.AreEqual(10, foo.CallBar()); } } Container 経由でインスタンスを生成できる Container のモック機能が使える
Mock<T> 便利 Moq ライブラリが提供する機能 https://github.com/moq モックを簡単に流し込めるのでテストが楽 OptionalExtras に入ってる // 何も返さなくていいとき
Container.Bind<IBar>().FromMock() // 明示的にメソッドの返り値をモックしたい時 var mock = new Mock<IBar>(); mock.Setup(b => b.Bar()).Returns(5); Container.BindInstance(mock.Object);
MonoBehavior が必要な処理 public class SpaceShip : MonoBehaviour { public Vector3
Velocity { get; set; } public void Update() { transform.position += Velocity * Time.deltaTime; } } Velocity が設定されたら動くかテストしたい
public class SpaceShipPlaymodeTest { [UnityTest] public IEnumerator SpaceShipPlaymodeTestWithEnumeratorPasses var spaceShip
= new GameObject("ship") .AddComponent<SpaceShip>(); spaceShip.Velocity = Vector3.up; Assert.AreEqual(spaceShip.transform.position, Vector3.ze yield return new WaitForSeconds(1F); Assert.Greater(spaceShip.transform.position.y, 0F); } }
MonoBehavior が必要な処理(Zenject) public class SpaceShip : MonoBehaviour { [Inject] public
Vector3 Velocity { get; private set; } public void Update() { transform.position += Velocity * Time.deltaTime; } }
Zenject in PlayMode public class SpaceShipTests : ZenjectIntegrationTestFixture { [UnityTest]
public IEnumerator TestVelocity() { PreInstall(); Container.Bind<SpaceShip>() .FromNewComponentOnNewGameObject() .AsSingle().WithArguments(Vector3.up); PostInstall(); var spaceShip = Container.Resolve<SpaceShip>(); Assert.AreEqual(spaceShip.transform.position, Vector3.ze yield return null; Assert.Greater(spaceShip.transform.position.y, 0F); } }
ZenjectIntegrationTestFixture がDI するためにいい感 じのメソッドを持っている PreInstall テスト用の準備をしてくれる Validation とかContext の生成とか PostIntall
バインドしたオブジェクトを注入する Run all in player には対応しておらず実機では走 らないので注意
所感 普通のテストとそんなにやり方は変わらない Zenject で書くべき! というかはInject してたら必 然的にテストもContainer 使わざるを得なくなるよ ねというお気持ち でもMoq
をサクッと使えるのは便利かも
余談1 unity-uitest https://github.com/taphos/unity-uitest uGUI 周りのテストを書きやすくしてくれるライブ ラリ クリックイベント辺りをやりやすくしてくれる UITest を継承する必要があるので ZenjectIntegrationTest
だと使いづらい
public class TestExample : UITest { [UnityTest] public IEnumerator Example()
{ // シー ン読み込み yield return LoadScene("TestableScene"); // Button オブジェクトを押したことにする yield return Press("Button"); // Foo/Text のラベルの文字を確認する yield return AssertLabel("Foo/Text", "Pressed!"); yield return Press("Close"); // FooWindow コンポー ネントがついたオブジェクトが非アクティブになる yield return WaitFor(new ObjectDisappeared<FooWindow>( } }
余談2 RuntimeUnitTestToolkit https://github.com/neuecc/RuntimeUnitTestToolkit @neuecc さんの作ったテストライブラリ 普通のシー ン上でテストを走らせてくれる アサー ションを再実装してシー ンで動くようにし
ている シー ン上での動作なので実機での確認も可能
None