初めての単体テスト

17,340 views

Published on

Xcode4での単体テストとその意味を語ってます

Published in: Technology
  • Be the first to comment

初めての単体テスト

  1. 1. 初めての単体テストXcodeでテストしてますか? バスケ Twitter: @basuke
  2. 2. Agenda• 単体テスト全般について• Xcode標準の単体テストを使う• テストしやすいコードとMVCについて• GHUnit - もうひとつの単体テスト環境• 位置情報系のテスト basuke
  3. 3. 単体テストとは?What is Unit Test? basuke
  4. 4. 単体テスト• Kent BeckさんがSmalltalk用に作った• Javaでブレーク、いろんな言語に飛び火• xUnitと呼ばれるフレームワーク• 単体テストの手法のメインストリーム• IDEなどのツールと相性が良い basuke
  5. 5. 単体テスト cont.• 小さい単位で機能をテストしていく• 簡単に実行、何度も実行• テストが仕様になる basuke
  6. 6. 単体テストの目的• コードの質を高められる• 書いたコードが動くことを確認できる • しかも継続的に• 設計の正当性を早期に検証できる• 客観的な視点を手に入れられる• 気持ちよくプログラミングできる basuke
  7. 7. 単体テスト向きでないこと• インターフェースの動作確認• グラフィカルな要素の正当性 • 線が正しく引けているか• 動作速度の検証• ストレステスト basuke
  8. 8. Xcodeの単体テスト環境 basuke
  9. 9. OCUnit -SenTestKit• Objective-C用のxUnitフレームワーク• Xcodeにバンドルされていて手軽• 一通りの機能は備えている• 新規プロジェクトでも既存でも簡単に テストを追加できる basuke
  10. 10. テスト用のターゲット• テストには専用ターゲットを用意する• 実行はテスト専用スキームを⌘-Uで簡 単に実行できる basuke
  11. 11. 通貨変換アプリを作って テストしてみよう#pragma mark - Actions- (IBAction)doConvert:(id)sender {! double anAmount = [amount.text doubleValue];! double aRate = [rate.text doubleValue];!! double aResult = [self convert:anAmount withRate:aRate];!! result.text = [[NSNumber numberWithDouble:aResult] stringValue];}#pragma mark - Logic- (double)convert:(double)anAmount withRate:(double)aRate {! return anAmount * aRate;} basuke
  12. 12. Xcodeで新規プロジェクト basuke
  13. 13. テストコード- (void)testConvert{! double result = [controller convert:78 withRate:78];! STAssertEquals(result, 1.0, @"¥78=$1");} basuke
  14. 14. アプリケーションテスト とロジックテスト basuke
  15. 15. 基本はアプリケーションテスト• デフォルトで作られるのはアプリケー ションテスト• 別にロジックテストというものもある basuke
  16. 16. ロジックテストとは• 手軽で迅速に動く • シミュレータに切り替わらない• ビルド設定で • Bundle LoaderとTest Hostを削除• 実際のアプリケーションの環境ではない ところでコードを実行する basuke
  17. 17. ロジックテストの欠点• シミュレータでしか動かない• 自分でコードをリンクしてあげる必要 がある• アプリケーションテストは勝手にリ ンクしてくれる• あくまでロジックの正当性をテスト basuke
  18. 18. Assertの種類 basuke
  19. 19. 同じ値を期待する• STAssertEqualObjects • オブジェクトがisEqual:か• STAssertEquals • 同じ値か• STAssertEqualsWithAccuracy • 幅を持たせた同値チェック basuke
  20. 20. NilとBOOLチェック• STAssertNil• STAssertNotNil • nil or not nil• STAssertTrue• STAssertFalse • YES or No basuke
  21. 21. 例外を捕捉したりしなかったり• STAssertThrows• STAssertThrowsSpecific• STAssertThrowsSpecificNamed• STAssertNoThrow• STAssertNoThrowSpecific• STAssertNoThrowSpecificNamed• STAssertTrueNoThrow• STAssertFalseNoThrow basuke
  22. 22. 必ず失敗させる• STFail • とりあえず失敗させておくときに使う • 後でテストを書かなくちゃ行けない場 合など• 到達してはいけない場合などにも使え る basuke
  23. 23. テストしやすいコード basuke
  24. 24. なぜテストしにくいか?• ViewControllerにロジックを入れている から• ロジックは独立したクラスに分離させ るべき• ViewControllerはグルーコードの固まり にすべき basuke
  25. 25. MVCが答え• 表示に関する詳細な実装はView• 入力に関する詳細な実装もView• それ以外のロジックはModel• データもModel• Modelでの状態の保持は最低限に basuke
  26. 26. 実例 basuke
  27. 27. View カスタムグラフビュー イベント カスタム ハンドリング タブバー basuke
  28. 28. Model 集計を更新する 毎月の集計グラフ用のデータを作る 昨年のデータ 日々記録するTwitterでつぶやく 日々のデータ basuke
  29. 29. Modelはテストできる• ただし、ちゃんと書かれたモデルは。• 外部に依存しないモデル• 状態を持っていても観測可能なモデル• 同じ状況で同じ値を渡したら同じ結果が 返ってくるモデル• 参照透明性 basuke
  30. 30. 電卓を作ってみよう• MVCの話をふまえた上で、どういう構 成にするか• 電卓のモデルは何か? basuke
  31. 31. GHUnitもうひとつの単体テスト環境 basuke
  32. 32. OCUnit vs GHUnit• Xcode 3時代はOCUnitは貧弱だった• GHUnitは救いだった• Xcode 4になってOCUnitが飛躍的に便利 になった• そんな状況な現在。 basuke
  33. 33. GHUnitの特徴• 見やすいテストランナー• オープンソース• 豊富なAssert• 非同期のテストをサポー ト• JenkinsによるCIサポート basuke
  34. 34. 非同期のテスト• GHAsyncTestCase • 非同期テストケース。別スレッドの完 了を待つことができる。• GHMockNSURLConnection • NSURLConnectionの動作をシミュレー トするクラス basuke
  35. 35. 導入は結構簡単• やってみましょう• http://gabriel.github.com/gh-unit/docs/ index.html basuke
  36. 36. Xcode4.2で導入された位置情報のテスト手法 basuke
  37. 37. 位置情報アプリのテスト• これまでは外に出るしかなかった• Xcode 4.2からシミュレータで位置情報 が返ってくるようになった• カスタマイズ可能 basuke
  38. 38. シミュレータの位置情報• 位置情報が返ってくる• 位置情報サービスの状態の管理• 位置情報サービス使用確認のリセット• 位置情報アイコンの表示• デバッグ > 位置 > カスタマイズ可能 basuke
  39. 39. Xcodeでの位置情報• Scheme単位で位置情報を変更できる• デバッガー実行中でも切り替えられる• メジャーな都市がプリセットで用意• GPXファイルをプロジェクトに追加す ることで、好きな場所に設定できる basuke
  40. 40. DEMO basuke

×