SlideShare a Scribd company logo
Unity編
GMO Pepabo, Inc.
HIROTO IMOTO
2015/12/13 Unity Fukuoka 09
テストを書こう
@adarapata
Imoto Hiroto
> GMOペパボ WEBエンジニア
> ロリポップ!開発やってる
> 業務ではruby + php
> 趣味でUnity
> 八耐によくいる
> ハッカソン好き
テスト書いてる?
今日話すこと
> テストコード
> Unity5.3のTest Runner
> Unityでのユニットテスト
今日話さないこと
> Unity Test Tools Asset
> Unity Integration Test
コードの動作確認
どうしてる?
こんなん書いて・・
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour {
// Use this for initialization
void Start () {
SugoiClass s = new SugoiClass();
Debug.Log(s.Sugoi());
}
}
動いた!OK!
置き場に困るTest.cs
都度改造されるTest.cs
using UnityEngine;
using System.Collections;
public class Test : MonoBehaviour {
// Use this for initialization
void Start () {
YabaiClass s = new YabaiClass();
Debug.Log(s.Yabai());
}
}
ほんとよくある
何をしたかった?
> 書いたコードが正しく動くか確認
> コンポーネントとして当てないと確
認できないので、Test.csを書いた
> 使い捨てコードを書きたいわけでは
ない!
コードが正しく動く
か確認したい
そういうのあります
テストコード
テストコードって?
> コードが正しい挙動か確認するため
のコード
> 技術というより文化
> 各言語に様々なテスティングフレー
ムワークがあったりする
> phpunit, rspec, JUnit etc…
例
using UnityEngine;
using System.Collections;
public class SugoiClass {
public string Sugoi()
{
return "Sugoi!!!!";
}
}
using UnityEngine;
using UnityEditor;
using NUnit.Framework;
public class SugoiClassTest {
[Test]
public void SugoiTest()
{
SugoiClass s = new SugoiClass();
Assert.AreEqual("Sugoi!!!!", s.Sugoi(), "Sugoi!!!!って返ってく��");
}
}
実装したクラス
テストコード
テストの種類(ごく一部)
> 単体テスト(Unit Test)
> 結合テスト(Integration Test)
> ググったらその他諸々出てきた・・
単体テスト
> Unit Testとも言う
> 一つ一つの機能の挙動をテストする
> だいたいメソッド単位でのテスト
> Unity5.3ではこれが書ける
> 粒度が小さいので書きやすい
結合テスト
> Integration Testとも言う
> 複数の機能が関連して動作するか
> マリオがクリボーを踏んだら倒せるか
> Unity5.3にはない
> UnityTestToolsには実装されている
Unityのテスト
> 2014年初頭にUnity公式がAsset
StoreにUnityTestToolsリリース
> Unity5.3にて、上記Assetの一部機
能(Test Runner)が取り込まれる
> NUnitが使われている
https://www.assetstore.unity3d.com/jp/#!/content/13802
TestRunner
> 書いたテストを実行するやつ
> Window->EditorTestsRunner
DEMO
基本の流れ
> Create -> Editor Test C# Script
> [Test]属性をメソッドに付ける
> Assertionを書く
> TestRunnerから実行
> 全部自動でやってくれる!
Assertionいろいろ
> AreEqual(expected, actual)
> expected == actual 値が等しいならパスする
> AreSame(expected, actual)
> Object.Equals(expected,actual) 同一オブジェクトならパスする
> IsTrue(condition)
> condition == true 真であるならパスする
> IsNull(anObject)
> anObject IS null NULLであるならパスする
> IsInstanceOf<T>(actual)
> actual IS T Tクラスであるならパスする
> Greater(arg1, arg2)
> arg1 > arg2 arg1の方がarg2より大きいならパスする
MonoBehaviourのユニットテスト
> Unitテストで書けるがちょっと苦手
> UnitTest内で各種Eventは呼ばれない
(Awake,Start,Update,Collision etc..)
> Undo.AddComponentで任意コンポーネ
ントの追加は可能
> Behaviourに実装したメソッドのテストく
らいなら・・
テストのメリット
> 変更に強い
> 理解のしやすさ
> コードの品質の向上
> 精神の安定
変更に強い
> 既存の改修、変更を行った場合の影響範囲を
どう調べるか
> 規模が大きいほど洗い出すの無理・・
> 変なとこからバグが出る・・
> 挙動が変わったらまずテストが落ちるので範
囲を絞り込める
> 結果的にテストプレ��よりは速くなりそう
理解のしやすさ
> そのクラスがどのように使われている
かがテストから判断できる
> テストコード = 1つの使用例
> 他の人(半年後の自分)が理解出来る
> テストコードがドキュメントである
> というのが一つの到達点・・・
コードの品質の向上
> ユニットテストしにくいコードとは
> 複数の要素が絡みまくってできない
> 密結合だったりすることが多い
> もっと良い書き方があるのでは?
> より良い設計への気づき・ヒントになる
> がっつり改修してもテストで動作を担保できる
精神の安定
> コードが正しく動くということが担
保されている安心感
> バグの存在にかなり気付きやすくな
る
> リファクタリング、新規コーディン
グへの抵抗を減らせる
テストのデメリット
> コーディングの作業量は増える
> もちろんコードが増えればテストも増える
> 最初は頑張ったけど〆切が近づくにつれてテストが
なくなるはよくある
> テストの記法の学習コスト
> Assertion、Mock、etc..
> ここに時間かけ続けてしまうと本末転倒になりがち
ちゃんとテストコード書いたら
人力テストはもうしなくていい?
それは無理
どこまでテストを書ける?
> 2014のUniteJapanでUnityTestToolsの
作者がその辺の話をしている
> http://japan.unity3d.com/unite/unite2014/files/
DAY2-1700-room1-Tomek.pdf
> https://vimeo.com/98119345
> 比率的には Unit >> Integration >>>>>>>> UI
> 見た目部分はまだまだ人の力が必要
> VIEWに依存しない低い部分はモリモリ書くべき(私見)
> 裏を返せばVIEWに依存するコードを書くと辛くなる
テスト駆動開発(TDD)
> 実際のコードより先にテストコードを
書く開発手法
> 失敗するテストを書く
> 上記のテストを通る最小限のコードを書く
> 最適化を行う
> 不要な処理を入れずにシンプルに書ける
テストを書き始めて・・・・
> 考える時間が増えた
> 「どんな機能が必要か」を考えた上でテス
トに起こすのでひたすら考える
> テスト通った瞬間が気持ちいい
> より設計に気を配れる。リファクタが楽
> 変なコード書いたらテスト落ちるし
まとめ
結局Unityでテスト書いたほうがいいの?
> 書いて損はない
> 現状だと痒いところに手が届かない感じ
> Monobehaviourのテストなど
> Unityならではの不具合もあったりする
> NUnit自体はC#であれば使えるので無駄にはならない
> IntegrationTestなど今後のアップデートには期待出
来る
> テスト文化自体は大事だから根付かせていくべき
まずは始めてみよう!
おまけ
> TestRunnerで実行した場合のstaticな値
はリセットされない。
> 例えばゲームのスコア(static)加算のテストとか書
いたら、テストのたびにスコアが増え続ける
> エディタからゲームを再生するタイミングで初期化
される
> そのテストを書かないか、テストコードの
最後に自前でリセットする処理を書こう
おまけ
> テスト内でインスタンスを普通に生成すると
テスト後にシーンに残り続ける
> シーン再生時みたいに状態を保持しているわけではな
いため。
> 生成する際はUndo.RegisterCreatedObjectUndo
メソッドを使おう
> http://docs.unity3d.com/ja/current/
ScriptReference/
Undo.RegisterCreatedObjectUndo.html

More Related Content

テストを書こう、Unity編