Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

4,745 views

Published on

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

Published in: Technology
  • Be the first to comment

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

  1. 1. ユニットテスト初学者が Kiwi framework 非同期テストで失敗した ヤフー vs クラスメソッド Buttle 6   Yuichi Adachi ! 2014 Feb 25 Copyright © Classmethod, Inc. 1
  2. 2. Self Introduction ! ! ・iOSアプリ開発&エンジニア歴もう少しで二年 ! ・去年12月にクラスメソッドに入社しました ! ・テスト歴は二ヶ月くらいです Copyright © Classmethod, Inc. 2
  3. 3. 今日話すこと ! ・Unit Test の利点 ! ・Kiwiの特徴 ! ・非同期テストでの失敗 Copyright © Classmethod, Inc. 3
  4. 4. Unit Testの利点 Copyright © Classmethod, Inc. 4
  5. 5. Unit Testの利点 ・ヘッダのコメント等では把握しきれない挙動  も把握できる。 Copyright © Classmethod, Inc. 5
  6. 6. Unit Testの利点 ・ヘッダのコメント等では把握しきれない挙動  も把握できる。 ! ・画面表示をせず、 +Uのみで挙動が期待する  内容かチェックできる。 Copyright © Classmethod, Inc. 6
  7. 7. Unit Testの利点 ・ヘッダのコメント等では把握しきれない挙動  も把握できる。 ! ・画面表示をせず、 +Uのみで挙動が期待する  内容かチェックできる。 ! ・副作用を含まないコードに貪欲になれる。 Copyright © Classmethod, Inc. 7
  8. 8. Kiwiの特徴 Copyright © Classmethod, Inc. 8
  9. 9. Kiwiの特徴 ! ・XCTest, OCUnitのようにテストメソッド名  を英語で逐一考えなくていい ! ! Copyright © Classmethod, Inc. 9
  10. 10. Kiwiの特徴 ! ・XCTest, OCUnitのようにテストメソッド名  を英語で逐一考えなくていい ! ・テストケースを対象ごと、文脈ごとに区切れる ! Copyright © Classmethod, Inc. 10
  11. 11. ! サーバーと切り離して 非同期ユニットテスト Copyright © Classmethod, Inc. 11
  12. 12. ! テストコードが 実行されない Copyright © Classmethod, Inc. 12
  13. 13. ! ソースURL: http://github.com/UsrNameu1/KiwiTestStudy Copyright © Classmethod, Inc. 13
  14. 14. テスト概略 Copyright © Classmethod, Inc. 14
  15. 15. テスト概略 Copyright © Classmethod, Inc. この部分を 15 テスト
  16. 16. テスト概略 Copyright © Classmethod, Inc. この部分を 16 テスト stub:withBlock: で置き換え
  17. 17. ブロックハンドラメソッド の挙動を決定 + (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block Copyright © Classmethod, Inc. 17
  18. 18. ブロックハンドラメソッド の挙動を決定 + (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block 返したいメソッドのセレクタを挿入 Copyright © Classmethod, Inc. 18
  19. 19. ブロックハンドラメソッド の挙動を決定 + (void)stub:(SEL)aSelector withBlock:(id (^)(NSArray *))block メソッド呼び出しの 引数、返り値を決め打ち ブロック引数はNSArray Copyright © Classmethod, Inc. 19 で取得できる
  20. 20. YADWebServiceSpec.m [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"]]; }]; }); Copyright © Classmethod, Inc. 20
  21. 21. YADWebServiceSpec.m [NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }]; Comments for describe, context, it }); it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; テスト コード }); Copyright © Classmethod, Inc. 21
  22. 22. YADWebServiceSpec.m [NSURLConnection stub:@selector(sendAsynchronousRequest:queue:completionHandler:) withBlock:^id(NSArray *params) { void (^handler)(NSURLResponse *, NSData *, NSError *) = params[2]; handler(nil, data, nil); return nil; }]; stub:withBlock: Comments for で置き換え describe, context, it }); it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; テスト コード }); Copyright © Classmethod, Inc. 22
  23. 23. Copyright © Classmethod, Inc. 23
  24. 24. BreakPointで ハンドラ内部が走っているか確認 Copyright © Classmethod, Inc. 24
  25. 25. YADWebServiceSpec.m [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"]]; }]; 使い分けてますか? }); Copyright © Classmethod, Inc. 25
  26. 26. YADWebServiceSpec.m [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"]]; }]; 使い分けてますか? }); Copyright © Classmethod, Inc. 26
  27. 27. 実行しない! Copyright © Classmethod, Inc. 27
  28. 28. ! Kiwi非同期ブロックハンドラ テストの注意点 Copyright © Classmethod, Inc. 28
  29. 29. ! Kiwi非同期ブロックハンドラ テストの注意点 ・ブロック内で結果を取得、ブロックの後で確認 ! Copyright © Classmethod, Inc. 29
  30. 30. ! Kiwi非同期ブロックハンドラ テストの注意点 ・ブロック内で結果を取得、ブロックの後で確認 ! ・expectFutureValue shouldEventually Copyright © Classmethod, Inc. 30
  31. 31. it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; Comments for describe, context, it }); Copyright © Classmethod, Inc. 31
  32. 32. it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; Comments for describe, context, it }); 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"]]; }); Copyright © Classmethod, Inc. 32
  33. 33. it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; Comments for describe, context, it }); 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"]]; }); Copyright © Classmethod, Inc. 33
  34. 34. it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; ぶ }); 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"]]; ブロック内で結果を取得、 ブロックの後で確認 }); Copyright © Classmethod, Inc. 34
  35. 35. it(@"ブロックハンドラから正常に値が帰ってくる", ^{ [webService fetchDataWithCompletion:^(NSDictionary *response, NSError *err) { [[response should] beNonNil]; [[response[@"id"] should] equal:object[@"id"]]; [[response[@"name"] should] equal:object[@"name"]]; }]; Comments for describe, context, it }); 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"]]; expectFutureValue shouldEventually }); Copyright © Classmethod, Inc. 35
  36. 36. Copyright © Classmethod, Inc. 36
  37. 37. 実行される! Copyright © Classmethod, Inc. 37
  38. 38. 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 Copyright © Classmethod, Inc. 38

×