Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Zenjectとテスト
Search
いも
March 20, 2018
Programming
0
8.2k
Zenjectとテスト
Gotanda.unity #5で発表するやつです
いも
March 20, 2018
Tweet
Share
More Decks by いも
See All by いも
UnityプログラミングバイブルR6号宣伝&Unity Logging小話
adarapata
0
430
Unityテスト活動のふりかえり
adarapata
1
530
Gather.townはいいぞ その後
adarapata
1
1.5k
Unityでの開発事例
adarapata
3
22k
どこのご家庭にもあるシーンマネージャーの話
adarapata
1
7.6k
Gather.townはいいぞ
adarapata
2
2.3k
宴はいいぞ
adarapata
0
1.3k
わかった気になるモブプログラミング
adarapata
1
98
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.2k
Other Decks in Programming
See All in Programming
Grafana Cloudとソラカメ
devoc
0
140
Djangoアプリケーション 運用のリアル 〜問題発生から可視化、最適化への道〜 #pyconshizu
kashewnuts
1
230
定理証明プラットフォーム lapisla.net
abap34
1
1.7k
Domain-Driven Transformation
hschwentner
2
1.9k
AWS Lambda functions with C# 用の Dev Container Template を作ってみた件
mappie_kochi
0
240
[JAWS-UG横浜 #80] うわっ…今年のServerless アップデート、少なすぎ…?
maroon1st
1
170
ファインディの テックブログ爆誕までの軌跡
starfish719
2
1.1k
SwiftUI Viewの責務分離
elmetal
PRO
0
140
お前もAI鬼にならないか?👹Bolt & Cursor & Supabase & Vercelで人間をやめるぞ、ジョジョー!👺
taishiyade
5
3.8k
Kanzawa.rbのLT大会を支える技術の裏側を変更する Ruby on Rails + Litestream 編
muryoimpl
0
220
GitHub Actions × RAGでコードレビューの検証の結果
sho_000
0
240
Immutable ActiveRecord
megane42
0
130
Featured
See All Featured
Writing Fast Ruby
sferik
628
61k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
29
2.2k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Testing 201, or: Great Expectations
jmmastey
41
7.2k
Unsuck your backbone
ammeep
669
57k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.4k
It's Worth the Effort
3n
184
28k
Making Projects Easy
brettharned
116
6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
59k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
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