kiwi 入門 | ios rdd テストフレームワーク

45
Yuki Tanabe iOS 用 RDD テストフレームワーク Kiwi 入門

Upload: yuki-tanabe

Post on 22-Jul-2015

291 views

Category:

Engineering


2 download

TRANSCRIPT

Page 1: Kiwi 入門 | iOS RDD テストフレームワーク

Yuki Tanabe

iOS 用 RDD テストフレームワーク !

Kiwi 入門

Page 2: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 3: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 4: Kiwi 入門 | iOS RDD テストフレームワーク

Kiwi とは

・BDD テストフレームワーク ・RSpec 的な書き方ができる ・command + U で実行可能 ・修正 BSD ライセンス

https://github.com/allending/Kiwi

Page 5: Kiwi 入門 | iOS RDD テストフレームワーク

BDD?

日本語的には、振る舞い駆動開発

仕様を振る舞いとして書くことで、 テストコードが仕様書の役割を果たす。

Page 6: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 7: Kiwi 入門 | iOS RDD テストフレームワーク

Kiwi を選ぶ理由

・仕様書作成&更新の手間がなくなる ・Xcode との相性が良い(⌘Uで実行できる) ・スタブ、モック、非同期処理のテストを標準装備 ・以前利用していた JavaScript の mocha と書き方が似てた

Page 8: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 9: Kiwi 入門 | iOS RDD テストフレームワーク

通常通りプロジェクト作成

Single View Application

Page 10: Kiwi 入門 | iOS RDD テストフレームワーク

プロジェクト名は Alpaca とする

通常通りプロジェクト作成

Page 11: Kiwi 入門 | iOS RDD テストフレームワーク

Alpaca?

いらない写真をサクサク消せる iPhone アプリです

https://itunes.apple.com/app/id934444072?mt=8

Page 12: Kiwi 入門 | iOS RDD テストフレームワーク

プロジェクト作成完了

通常通りプロジェクト作成

Page 13: Kiwi 入門 | iOS RDD テストフレームワーク

テストコードの在処

ここにテストコード を追加していく(AlpacaTests.m は消しておく)

Page 14: Kiwi 入門 | iOS RDD テストフレームワーク

Kiwi の導入

cocoapods で導入できる

source 'https://github.com/CocoaPods/Specs.git'platform :ios, '7.0'!target :AlpacaTests, :exclusive => true do pod 'Kiwi'end

Podfile

Page 15: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 16: Kiwi 入門 | iOS RDD テストフレームワーク

今回作ってみるサンプル

クラスの概要 アプリへのセッション回数を管理するクラス !クラス名 SessionCounter!メソッド +(void)countUp; // セッションカウントを増やす +(BOOL)isFirstSession; // 初回セッションかどうか

Page 17: Kiwi 入門 | iOS RDD テストフレームワーク

テストケースクラスの追加

Test Case Class を選択

Page 18: Kiwi 入門 | iOS RDD テストフレームワーク

クラス名を入力

[対象クラス名]Spec と命名

Page 19: Kiwi 入門 | iOS RDD テストフレームワーク

テストケースクラス作成完了

できた!

Page 20: Kiwi 入門 | iOS RDD テストフレームワーク

XCTest 的記述を除去

@interface 以下を全削除

Page 21: Kiwi 入門 | iOS RDD テストフレームワーク

テスト対象クラスを追加

SessionCounter追加>メソッド定義

Page 22: Kiwi 入門 | iOS RDD テストフレームワーク

テストコード側で import

Kiwi と対象クラスを import

Page 23: Kiwi 入門 | iOS RDD テストフレームワーク

テストのベース部分を追加

SPEC_BEGIN ~ SPEC_END まで記述

Page 24: Kiwi 入門 | iOS RDD テストフレームワーク

SPEC_* ?

SPEC_BEGIN @interface や @implementation を実装したマクロ !SPEC_END @end を実装したマクロ

KiwiMacros.h

Page 25: Kiwi 入門 | iOS RDD テストフレームワーク

describe?

describe クラス、メソッドなどのテスト対象を記述する

describe(@"SessionCounter のテスト", ^{ // ここにテストコードを書いていく});

Page 26: Kiwi 入門 | iOS RDD テストフレームワーク

テストを書く

describe(@"SessionCounter のテスト", ^{ context(@"初期状態", ^{ it(@"isFirstSession は NO が返る", ^{ BOOL sessionCount = [SessionCounter isFirstSession]; [[theValue(sessionCount) should] equal:theValue(NO)]; }); });});

SessionCounterSpec.m

Page 27: Kiwi 入門 | iOS RDD テストフレームワーク

context? it?

context テスト対象の状態、状況を記述 !

it この状態・入力の時に、どう振る舞うべきか。 期待される出力を記述

Page 28: Kiwi 入門 | iOS RDD テストフレームワーク

Assertion

describe(@"SessionCounter のテスト", ^{ context(@"初期状態", ^{ it(@"isFirstSession は NO が返る", ^{ BOOL isFirstSession = [SessionCounter isFirstSession]; [[theValue(isFirstSession) should] equal:theValue(NO)]; }); });});

isFirstSession should equal NO.Assertion が直感的で分かりやすい

Page 29: Kiwi 入門 | iOS RDD テストフレームワーク

テストコードの可読性が高い

describe(@"SessionCounter のテスト", ^{ context(@"初期状態", ^{ it(@"isFirstSession は NO が返る", ^{ BOOL isFirstSession = [SessionCounter isFirstSession]; [[theValue(isFirstSession) should] equal:theValue(NO)]; }); });});

SessionCounterSpec.m

Page 30: Kiwi 入門 | iOS RDD テストフレームワーク

テストを作り上げて、実装

細かい流れは割愛しますが、 本来は最小限のテストを書いた後に テスト(仕様書)を作り上げてから、 対象クラスをテストが通るまで実装

Page 31: Kiwi 入門 | iOS RDD テストフレームワーク

テストを通るようにクラス修正

Page 32: Kiwi 入門 | iOS RDD テストフレームワーク

テストを追加

context(@"1回目のセッション", ^{ beforeAll(^{ [SessionCounter countUp]; }); it(@"isFirstSession は YES が返る", ^{ BOOL sessionCount = [SessionCounter isFirstSession]; [[theValue(sessionCount) should] equal:theValue(YES)]; }); }); context(@"2回目のセッション", ^{ beforeAll(^{ [SessionCounter countUp]; }); it(@"isFirstSession は NO が返る", ^{ BOOL sessionCount = [SessionCounter isFirstSession]; [[theValue(sessionCount) should] equal:theValue(NO)]; }); });

Page 33: Kiwi 入門 | iOS RDD テストフレームワーク

最終形

Page 34: Kiwi 入門 | iOS RDD テストフレームワーク

最終形

Page 35: Kiwi 入門 | iOS RDD テストフレームワーク

beforeAll? afterAll?

beforeAll ブロック内の最初に一度だけ実行される !

afterAll ブロック内の最後に一度だけ実行される

初期化処理や後処理、 事前・事後にすべき操作をここで書く

Page 36: Kiwi 入門 | iOS RDD テストフレームワーク

他にも...

beforeEach ブロック内の it の直前に毎回実行される !

afterEach ブロック内の it の直後に毎回実行される

Page 37: Kiwi 入門 | iOS RDD テストフレームワーク

テスト実行方法command + U で実行

成功すると緑に✓

Page 38: Kiwi 入門 | iOS RDD テストフレームワーク

実際の作業の進め方

0. テストとテスト対象の疎通確認まで 1. テストを書く 2. テスト対象のコードを書く 3. テストが成功するまで実装 4. リファクタリングする 5. テストが通るまで実装

Page 39: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 40: Kiwi 入門 | iOS RDD テストフレームワーク

得られる恩恵

・コード変更やリファクタリングがしやすくなる ・複数人開発時にバグ混入を防げる ・仕様書=テストコードなので  仕様変更の度にドキュメントを編集する必要なし

Page 41: Kiwi 入門 | iOS RDD テストフレームワーク

発表の流れ

・Kiwi とは ・Kiwi を選ぶ理由 ・Kiwi の導入方法 ・Kiwi でテストを書く ・得られる恩恵 ・いつテストを書く?

Page 42: Kiwi 入門 | iOS RDD テストフレームワーク

いつテストを書く?

・新規クラス追加時  仕様を書きながらクラス追加 !

・実装変更やリファクタリング時  実装変更前にテスト導入  実装変更後にテストが通ることを確認

Page 43: Kiwi 入門 | iOS RDD テストフレームワーク

サンプルコード

https://github.com/tanabee/Alpacagithub

Page 45: Kiwi 入門 | iOS RDD テストフレームワーク

ご清聴ありがとうございました