Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Test techniques for iOS app using Web API
Search
cockscomb
April 24, 2014
Programming
4
38k
Test techniques for iOS app using Web API
My presentation at Consumer Service Engineer MeetUp Vol.1 ~iOS編~ (
http://eventdots.jp/event/47442
)
cockscomb
April 24, 2014
Tweet
Share
More Decks by cockscomb
See All by cockscomb
jq at the Shortcuts
cockscomb
1
1.9k
GraphQL放談
cockscomb
4
2k
GraphQL Highway
cockscomb
28
8.6k
吉田を支える技術
cockscomb
0
2.4k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.4k
ユーザインターフェイスと非同期処理
cockscomb
5
1.9k
GUIアプリケーションの構造と設計
cockscomb
10
10k
イカリング2におけるシングルページアプリケーション
cockscomb
2
7.6k
あなたの知らない UIKit の世界 — UITableView に UITextView を置きたい
cockscomb
1
7.5k
Other Decks in Programming
See All in Programming
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
0
790
デミカツ切り抜きで面倒くさいことはPythonにやらせよう
aokswork3
0
260
Building, Deploying, and Monitoring Ruby Web Applications with Falcon (Kaigi on Rails 2025)
ioquatix
4
2.5k
品質ワークショップをやってみた
nealle
0
600
コードとあなたと私の距離 / The Distance Between Code, You, and I
hiro_y
0
190
TFLintカスタムプラグインで始める Terraformコード品質管理
bells17
2
350
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
550
SwiftDataを使って10万件のデータを読み書きする
akidon0000
0
230
ソフトウェア設計の実践的な考え方
masuda220
PRO
4
630
理論と実務のギャップを超える
eycjur
0
170
XP, Testing and ninja testing ZOZ5
m_seki
3
790
Domain-centric? Why Hexagonal, Onion, and Clean Architecture Are Answers to the Wrong Question
olivergierke
3
940
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1032
470k
Reflections from 52 weeks, 52 projects
jeffersonlam
353
21k
Making Projects Easy
brettharned
120
6.4k
Facilitating Awesome Meetings
lara
57
6.6k
Mobile First: as difficult as doing things right
swwweet
225
10k
What’s in a name? Adding method to the madness
productmarketing
PRO
24
3.7k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Making the Leap to Tech Lead
cromwellryan
135
9.6k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
15k
It's Worth the Effort
3n
187
28k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
Producing Creativity
orderedlist
PRO
347
40k
Transcript
Web APIΛར༻͢Δ iOSΞϓϦͷςετٕ๏
None
cockscomb
id:cockscomb ΞϓϦέʔγϣϯΤϯδχΞ iOSΞϓϦɾWebΞϓϦέʔγϣϯ Perl, JavaScript, Objective-C ͯͳϒϩάνʔϜ WWDC 2014
ͯͳϒϩά Presso B!KUMA Ψʔϧζ
ͯͳαϚʔΠϯλʔϯ Web APIΛར༻͢ΔiOSΞϓϦ࡞
–id:murakaming “iOS ଆͬ͟ͱݟ͚ͨͲɺ͜͏͍͏ حྷͳίʔυ͕খ͍͞αϯϓϧͰͳ͘ Ұࣜἧ͍ͬͯΔͷຊʹوॏͩ͠ ༗Γ͗͢Δɻ”
–id:griffin-stewie “ͦΕͳΓʹ࣮ઓܦݧ͕͋ΔਓͰ ͬͯͳͦ͞͏ͩͬͨΓΒͳͦ͏ͳ͜ͱΛ αϥοͱݟͤͯ͘Ε͍ͯΔ”
Web APIΛར༻͢Δ iOSΞϓϦͷςετٕ๏
Web API JSON REST·ͨAppઐ༻ APIόʔδϣϯ
API is living
ੜ͖͍ͯΔAPIͷͨΊͷ ςετ
ԿΛςετ͢Δͷ͔ ظͲ͓ΓͷHTTP request͕ൃߦ͞ΕΔ URL (ϗετύεɺΫΤϦ) HTTP method, header, body ༷ʑͳHTTP
responseʹର͢Δ;Δ·͍ Τϥʔ͕ى͖ͨͱ͖
ಓ۩ • OHHTTPStubs • NTLHTTPStubServer
OHHTTPStubs • HTTPͷ௨৴Λstub͢Δ • NSURLProtocolΛར༻͍ͯ͠Δ
__block APIClient *client; __block NSURLRequest *lastRequest; __block OHHTTPStubsResponse *preferredResponse; !
beforeAll(^{ client = [APIClient sharedClient]; ! [OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { if ( [request.HTTPMethod isEqual:@"GET"] && [request.URL.host isEqual:@"example.com"] && [request.URL.path isEqual:@"/api/entries.json"] ) { lastRequest = request; return YES; } return NO; } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { return preferredResponse; }]; }); ! afterEach(^{ lastRequest = nil; preferredResponse = nil; }); ! afterAll(^{ [OHHTTPStubs removeAllStubs]; });
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) { if ( [request.HTTPMethod isEqual:@"GET"] && [request.URL.host
isEqual:@"example.com"] && [request.URL.path isEqual:@"/api/entries.json"] ) { lastRequest = request; return YES; } return NO; } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { return preferredResponse; }];
NSString *userAgent = lastRequest.allHTTPHeaderFields[@"User-Agent"]; expect([userAgent hasPrefix:@"BKUMAGirls"]).to.beTruthy(); ! ! NSURL *URL
= lastRequest.URL; NSDictionary *query = [CMDQueryStringSerialization dictionaryWithQueryString:URL.query]; ! expect(query[@"entry_id"]).to.equal(@"1234567890");
preferredResponse = [OHHTTPStubsResponse responseWithFileAtPath: OHPathForFileInBundle(@"entries.json", nil) statusCode:200 headers:@{ @"Content-Type" :
@"application/json", }]; ! ! preferredResponse = [OHHTTPStubsResponse responseWithJSONObject:@{ @"test" : @"ok", } statusCode:200 headers:@{ @"Content-Type" : @"application/json", }]; ! ! preferredResponse = [OHHTTPStubsResponse responseWithError: [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorNetworkConnectionLost userInfo:nil]];
OHHTTPStubs • HTTP requestͷ༷ࢠΛݟΔ͜ͱ͕Ͱ͖Δ • ҙͷHTTP responseΛฦ͢͜ͱ͕Ͱ͖Δ • ΤϥʔΛൃੜͤ͞ΒΕΔ •
HTTP bodyऔಘͰ͖ͳ͍
NLTHTTPStubServer • ΞϓϦͷ෦ͰαʔόʔΛಈ͔͢ • CocoaHTTPServerΛར༻ • http://localhost:12345/
#if defined(UNIT_TEST) static NSString *const kAPIRootURLString = @"http://localhost:12345/"; #else static
NSString *const kAPIRootURLString = @"http://example.com/"; #endif
__block NLTHTTPStubServer *server; __block APIClient *client; ! beforeAll(^{ server =
[[NLTHTTPStubServer alloc] init]; [server startServer]; client = [APIClient sharedClient]; }); ! afterAll(^{ [server stopServer]; }); ! afterEach(^{ [server clear]; });
[[[[server expect] forPath:@"/api/bookmarks.json" HTTPMethod:@"POST"] andCheckPostBody:^(NSData *postBody) { ! NSString *body
= [[NSString alloc] initWithData:postBody encoding:NSUTF8StringEncoding]; ! NSDictionary *parameters = [CMDQueryStringSerialization dictionaryWithQueryString:body]; ! expect(parameters[@"entry_id"]).to.equal(@"1234567890"); ! }] andPlainResponse:[@"1" dataUsingEncoding:NSUTF8StringEncoding]]; ! ... ! [server verify];
NLTHTTPStubServer • ࣮ࡍͷαʔόʔͱͯ͠ৼΔ͏ • ҙͷHTTP responseΛฦ͢͜ͱ͕Ͱ͖Δ • HTTP bodyͷ༷ࢠΛݟΔ͜ͱ͕Ͱ͖Δ •
Τϥʔൃੜͤ͞ΒΕͳ͍ • HTTP requestҰ෦औಘͰ͖ͳ͍
ಓ۩ • OHHTTPStubs • NTLHTTPStubServer
ςετͷϝϦοτ • ࣗ༝ͳHTTP response͕࡞ΕΔ • ࣮ࡍʹαʔόʔʹrequest͠ͳͯ͘Α͍ • αʔόʔαΠυͷ࣮Λͭඞཁ͕ͳ͍ • αʔόʔαΠυͷมߋΛࣄલʹࢼͤΔ
• ͍͖ͳΓյΕΔͷΛ͛Δ
ςετ is ศར
None
PR
[PR] ৽αʔϏεΓ·͢ https://mackerel.io/ ϕʔλϢʔβʔ ࣄલडத!!
ੵۃ࠾༻த http://hatenacorp.jp/recruit/