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
440
Unityテスト活動のふりかえり
adarapata
1
530
Gather.townはいいぞ その後
adarapata
1
1.5k
Unityでの開発事例
adarapata
3
22k
どこのご家庭にもあるシーンマネージャーの話
adarapata
1
7.7k
Gather.townはいいぞ
adarapata
2
2.3k
宴はいいぞ
adarapata
0
1.4k
わかった気になるモブプログラミング
adarapata
1
99
モブワークっぽいのをやっている話/Trying mobwork
adarapata
2
1.2k
Other Decks in Programming
See All in Programming
コミュニティ駆動 AWS CDK ライブラリ「Open Constructs Library」 / community-cdk-library
gotok365
2
250
Better Code Design in PHP
afilina
0
180
Swift Testingのモチベを上げたい
stoticdev
2
120
第3回関東Kaggler会_AtCoderはKaggleの役に立つ
chettub
3
1.2k
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
14
4.7k
Ça bouge du côté des animations CSS !
goetter
2
150
GoとPHPのインターフェイスの違い
shimabox
2
210
責務と認知負荷を整える! 抽象レベルを意識した関心の分離
yahiru
8
1.4k
未経験でSRE、はじめました! 組織を支える役割と軌跡
curekoshimizu
1
160
Datadog Workflow Automation で圧倒的価値提供
showwin
1
230
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
190
Bedrock Agentsレスポンス解析によるAgentのOps
licux
3
930
Featured
See All Featured
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
10
520
What's in a price? How to price your products and services
michaelherold
244
12k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
10
1.3k
GraphQLとの向き合い方2022年版
quramy
44
14k
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7.1k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
A Tale of Four Properties
chriscoyier
158
23k
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
The Cult of Friendly URLs
andyhume
78
6.2k
Raft: Consensus for Rubyists
vanstee
137
6.8k
Building Adaptive Systems
keathley
40
2.4k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
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