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
540
Unityテスト活動のふりかえり
adarapata
1
570
Gather.townはいいぞ その後
adarapata
1
1.6k
Unityでの開発事例
adarapata
3
22k
どこのご家庭にもあるシーンマネージャーの話
adarapata
1
8.1k
Gather.townはいいぞ
adarapata
2
2.4k
宴はいいぞ
adarapata
0
1.5k
わかった気になるモブプログラミング
adarapata
1
120
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.3k
Other Decks in Programming
See All in Programming
AIコーディングエージェント全社導入とセキュリティ対策
hikaruegashira
12
7.2k
マッチングアプリにおけるフリックUIで苦労したこと
yuheiito
0
240
ご注文の差分はこちらですか? 〜 AWS CDK のいろいろな差分検出と安全なデプロイ
konokenj
4
670
202507_ADKで始めるエージェント開発の基本 〜デモを通じて紹介〜(奥田りさ)
risatube
PRO
3
550
リッチエディターを安全に開発・運用するために
unachang113
1
240
型で語るカタ
irof
0
800
Claude Code + Container Use と Cursor で作る ローカル並列開発環境のススメ / ccc local dev
kaelaela
12
7.4k
おやつのお供はお決まりですか?@WWDC25 Recap -Japan-\(region).swift
shingangan
0
150
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
5
9.3k
商品比較サービス「マイベスト」における パーソナライズレコメンドの第一歩
ucchiii43
0
200
Workers を定期実行する方法は一つじゃない
rokuosan
0
130
Gemini CLIの"強み"を知る! Gemini CLIとClaude Codeを比較してみた!
kotahisafuru
2
150
Featured
See All Featured
Fashionably flexible responsive web design (full day workshop)
malarkey
407
66k
Intergalactic Javascript Robots from Outer Space
tanoku
271
27k
The Pragmatic Product Professional
lauravandoore
35
6.8k
Automating Front-end Workflow
addyosmani
1370
200k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3.3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
26
2.9k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Faster Mobile Websites
deanohume
308
31k
Gamification - CAS2011
davidbonilla
81
5.4k
Become a Pro
speakerdeck
PRO
29
5.4k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
The Invisible Side of Design
smashingmag
301
51k
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