ユニットテスト初学者がKiwiFramework非同期テストで失敗した

39
Copyright © Classmethod, Inc. ユニットテスト初学者が Kiwi framework 非同期テストで失敗した Yuichi Adachi 2014 Feb 25 1 ヤフー vs クラスメソッド Buttle 6

description

ヤフー vs クラスメソッド Buttle6 発表資料

Transcript of ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Page 1: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

ユニットテスト初学者が Kiwi framework

非同期テストで失敗した

Yuichi Adachi   !

2014 Feb 25

�1

ヤフー vs クラスメソッド Buttle 6

Page 2: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �2

Self Introduction!!・iOSアプリ開発&エンジニア歴もう少しで二年 !・去年12月にクラスメソッドに入社しました !・テスト歴は二ヶ月くらいです

Page 3: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �3

今日話すこと

!

・Unit Test の利点 !

・Kiwiの特徴 !

・非同期テストでの失敗

Page 4: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �4

Unit Testの利点

Page 5: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

・ヘッダのコメント等では把握しきれない挙動  も把握できる。

�5

Unit Testの利点

Page 6: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

・ヘッダのコメント等では把握しきれない挙動  も把握できる。 !・画面表示をせず、⌘+Uのみで挙動が期待する  内容かチェックできる。

�6

Unit Testの利点

Page 7: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

・ヘッダのコメント等では把握しきれない挙動  も把握できる。 !・画面表示をせず、⌘+Uのみで挙動が期待する  内容かチェックできる。 !・副作用を含まないコードに貪欲になれる。

�7

Unit Testの利点

Page 8: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

Kiwiの特徴

�8

Page 9: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

Kiwiの特徴

!・XCTest, OCUnitのようにテストメソッド名  を英語で逐一考えなくていい !!

�9

Page 10: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

Kiwiの特徴

!・XCTest, OCUnitのようにテストメソッド名  を英語で逐一考えなくていい !・テストケースを対象ごと、文脈ごとに区切れる !

�10

Page 11: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

!

サーバーと切り離して 非同期ユニットテスト

�11

Page 12: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

!

テストコードが 実行されない

�12

Page 13: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

!

ソースURL: http://github.com/UsrNameu1/KiwiTestStudy

�13

Page 14: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �14

テスト概略

Page 15: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �15

テスト概略

この部分を テスト

Page 16: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �16

テスト概略

この部分を テスト

stub:withBlock: で置き換え

Page 17: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �17

ブロックハンドラメソッド の挙動を決定

+ (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block

Page 18: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �18

+ (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block

返したいメソッドのセレクタを挿入

ブロックハンドラメソッド の挙動を決定

Page 19: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �19

+ (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block

メソッド呼び出しの 引数、返り値を決め打ち ブロック引数はNSArray

で取得できる

ブロックハンドラメソッド の挙動を決定

Page 20: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

[NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }];});it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

�20

YADWebServiceSpec.m

Page 21: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

Comments for describe, context, it

[NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }];});it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

�21

YADWebServiceSpec.m

テスト コード

Page 22: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

Comments for describe, context, it

[NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }];});it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

�22

YADWebServiceSpec.m

stub:withBlock: で置き換え

テスト コード

Page 23: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �23

Page 24: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

BreakPointで ハンドラ内部が走っているか確認

�24

Page 25: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

!

!

テストに対するコメント 使い分けてますか?

�25

[NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }];});it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

YADWebServiceSpec.m

Page 26: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

!

!

テストに対するコメント 使い分けてますか?

�26

[NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }];});it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

YADWebServiceSpec.m

Page 27: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

実行しない!

�27

Page 28: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �28

!

Kiwi非同期ブロックハンドラ テストの注意点

Page 29: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

・ブロック内で結果を取得、ブロックの後で確認 !

�29

!

Kiwi非同期ブロックハンドラ テストの注意点

Page 30: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

・ブロック内で結果を取得、ブロックの後で確認 !・expectFutureValue shouldEventually

�30

!

Kiwi非同期ブロックハンドラ テストの注意点

Page 31: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

Comments for describe, context, it

�31

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

Page 32: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ __block NSDictionary *res; [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { res = response; }]; [[expectFutureValue(res) shouldEventually] beNonNil]; [[expectFutureValue(res[@"id"]) shouldEventually] equal:object[@"id"]]; [[expectFutureValue(res[@"name"]) shouldEventually] equal:object[@"name"]]; });

Comments for describe, context, it

�32

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

Page 33: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ __block NSDictionary *res; [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { res = response; }]; [[expectFutureValue(res) shouldEventually] beNonNil]; [[expectFutureValue(res[@"id"]) shouldEventually] equal:object[@"id"]]; [[expectFutureValue(res[@"name"]) shouldEventually] equal:object[@"name"]]; });

Comments for describe, context, it

�33

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

Page 34: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ __block NSDictionary *res; [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { res = response; }]; [[expectFutureValue(res) shouldEventually] beNonNil]; [[expectFutureValue(res[@"id"]) shouldEventually] equal:object[@"id"]]; [[expectFutureValue(res[@"name"]) shouldEventually] equal:object[@"name"]]; });

�34

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

ブロック内で結果を取得、 !

ブロックの後で確認

Page 35: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ __block NSDictionary *res; [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { res = response; }]; [[expectFutureValue(res) shouldEventually] beNonNil]; [[expectFutureValue(res[@"id"]) shouldEventually] equal:object[@"id"]]; [[expectFutureValue(res[@"name"]) shouldEventually] equal:object[@"name"]]; });

Comments for describe, context, it

�35

it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }];});

expectFutureValue shouldEventually

Page 36: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �36

Page 37: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc. �37

実行される!

Page 38: ユニットテスト初学者がKiwiFramework非同期テストで失敗した

Copyright © Classmethod, Inc.

References!!・Asynchronous Testing - allending/Kiwi Wiki

last edited by Dave Meehan, cited 2014 Feb 09  Available from :

https://github.com/allending/Kiwi/wiki/Asynchronous-Testing

�38

Page 39: ユニットテスト初学者がKiwiFramework非同期テストで失敗した