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

Post on 08-May-2015

3.573 views 1 download

description

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

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

Copyright © Classmethod, Inc.

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

非同期テストで失敗した

Yuichi Adachi   !

2014 Feb 25

�1

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

Copyright © Classmethod, Inc. �2

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

Copyright © Classmethod, Inc. �3

今日話すこと

!

・Unit Test の利点 !

・Kiwiの特徴 !

・非同期テストでの失敗

Copyright © Classmethod, Inc. �4

Unit Testの利点

Copyright © Classmethod, Inc.

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

�5

Unit Testの利点

Copyright © Classmethod, Inc.

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

�6

Unit Testの利点

Copyright © Classmethod, Inc.

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

�7

Unit Testの利点

Copyright © Classmethod, Inc.

Kiwiの特徴

�8

Copyright © Classmethod, Inc.

Kiwiの特徴

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

�9

Copyright © Classmethod, Inc.

Kiwiの特徴

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

�10

Copyright © Classmethod, Inc.

!

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

�11

Copyright © Classmethod, Inc.

!

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

�12

Copyright © Classmethod, Inc.

!

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

�13

Copyright © Classmethod, Inc. �14

テスト概略

Copyright © Classmethod, Inc. �15

テスト概略

この部分を テスト

Copyright © Classmethod, Inc. �16

テスト概略

この部分を テスト

stub:withBlock: で置き換え

Copyright © Classmethod, Inc. �17

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

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

Copyright © Classmethod, Inc. �18

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

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

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

Copyright © Classmethod, Inc. �19

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

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

で取得できる

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

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

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

テスト コード

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: で置き換え

テスト コード

Copyright © Classmethod, Inc. �23

Copyright © Classmethod, Inc.

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

�24

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

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

Copyright © Classmethod, Inc.

実行しない!

�27

Copyright © Classmethod, Inc. �28

!

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

Copyright © Classmethod, Inc.

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

�29

!

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

Copyright © Classmethod, Inc.

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

�30

!

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

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"]]; }];});

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"]]; }];});

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"]]; }];});

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"]]; }];});

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

ブロックの後で確認

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

Copyright © Classmethod, Inc. �36

Copyright © Classmethod, Inc. �37

実行される!

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