Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
2013-01-10 iOS testing
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
CocoaHeads Tricity
January 10, 2013
Programming
81
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
2013-01-10 iOS testing
CocoaHeads Tricity
January 10, 2013
More Decks by CocoaHeads Tricity
See All by CocoaHeads Tricity
2013-05-15 Threads. Why and how.
cocoaheadstricity
0
87
2013-05-15 The story of Taxi5.pl. How to get 2mln PLN from a VC
cocoaheadstricity
0
89
2013-04-16 iOS development speed up
cocoaheadstricity
0
110
2013-04-16 cocos2d & chipmunk
cocoaheadstricity
0
79
2013-03-07 iOS indie developer toolkit
cocoaheadstricity
1
91
2013-02-05 UICollectionView
cocoaheadstricity
0
200
2013-02-05 UXDesignForMobileApps
cocoaheadstricity
1
120
Other Decks in Programming
See All in Programming
Agents on Rails - Rails at Scale 2026
irinanazarova
0
520
Kubernetes祭り #2 OP/ED
bells17
0
110
phperだってパンチカードでコーディングしたい
o0h
PRO
0
250
カツオ、ご期待ください
suneo3476
0
160
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
120
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
360
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
170
R8 の設定見直しでアプリサイズ削減
andpad
0
190
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
120
[ハンズオン]AIへの指示だけで「五目並べ」を作ってみよう
satoshi256kbyte
1
360
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
450
SREの越境 / SRE Collaboration
y0hgi
2
300
Featured
See All Featured
StorybookのUI Testing Handbookを読んだ
zakiyama
31
7k
[SF Ruby Conf 2025] Rails X
palkan
3
1.4k
Making the Leap to Tech Lead
cromwellryan
135
10k
How to build a perfect <img>
jonoalderson
1
6.1k
The Cult of Friendly URLs
andyhume
79
7k
Done Done
chrislema
187
17k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
580
New Earth Scene 8
popppiees
4
2.7k
Large-scale JavaScript Application Architecture
addyosmani
516
110k
A Modern Web Designer's Workflow
chriscoyier
699
190k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.9k
4 Signs Your Business is Dying
shpigford
187
23k
Transcript
Testing in iOS 10.01.2013 by Tomasz Janeczko
About me Tomasz Janeczko • iOS developer in Kainos •
Enthusiast of business, electronics, Rails & Heroku • Organizer of first App Camp in UK and PL
So let’s talk about testing.
Why we test?
None
So?
• Reliability • Regression • Confidence (e.g. refactoring)
Why not to test?
Why not to test? • Heavy dependence on UI •
Non-testable code • Bad framework
How to address issues • Sample - downloading stuff from
interwebz
First fault Writing tests after writing code
Separation of concerns
Separation of concerns • Let’s separate out the UI code
• Same for services interaction
Demo of tests
Writing tests Meet Kiwi and OCMock
Kiwi • RSpec-like tests writing • Matchers • Cleaner and
more self-descriptive code
Kiwi describe(@"Tested class", ^{ context(@"When created", ^{ it(@"should not fail",
^{ [[theValue(0) should] equal:theValue(0)]; }); }); });
Kiwi describe(@"Tested class", ^{ context(@"When created", ^{ it(@"should not fail",
^{ id viewController = [ViewController new]; [[viewController should] conformToProtocol:@protocol(UITableViewDelegate)]; }); }); });
Matchers [subject shouldNotBeNil] • [subject shouldBeNil] • [[subject should] beIdenticalTo:(id)anObject]
- compares id's • [[subject should] equal:(id)anObject] • [[subject should] equal:(double)aValue withDelta: (double)aDelta] • [[subject should] beWithin:(id)aDistance of:(id)aValue] • [[subject should] beLessThan:(id)aValue] • etc. etc.
Compare to SenTesting Kit [[subject should] equal:anObject] compare with STAssertEquals(subject,
anObject, @”Should be equal”);
OCMock • Mocking and stubbing library for iOS • Quite
versatile • Makes use of NSProxy magic
Sample workflows
Classic calculator sample describe(@"Calculator", ^{
context(@"with the numbers 60 and 5 entered", ^{ RPNCalculator *calculator = [[RPNCalculator alloc] init]; beforeEach(^{ [calculator enter:60]; [calculator enter:5]; }); afterEach(^{ [calculator clear]; }); it(@"returns 65 as the sum", ^{ [[theValue([calculator add]) should] equal:65 withDelta:.01]; });
Test if calls dep methods 1. Create a mock dependency
2. Inject it 3. Call the method 4. Verify
Test dependency // Create the tested object and mock to
exchange part of the functionality viewController = [ViewController new]; mockController = [OCMockObject partialMockForObject:viewController]; // Create the mock and change implementation to return our class id serviceMock = [OCMockObject mockForClass:[InterwebzService class]]; [[[mockController stub] andReturn:serviceMock] service]; // Define expectations [[serviceMock expect] downloadTweetsJSONWithSuccessBlock:[OCMArg any]]; // Run the tested method [viewController tweetsButtonTapped:nil]; // Verify - throws exception on failure [mockController verify];
Testing one layer • Isolate dependencies • Objective-C is highly
dynamic - we can change implementations of private methods or static methods • We can avoid IoC containers for testing
Accessing private methods
Accessing private methods @interface ViewController() - (void)startDownloadingTweets; @end ... [[mockController
expect] startDownloadingTweets];
Static method testing • Through separation to a method @interface
ViewController() - (NSUserDefaults *)userDefaults; @end ... id mockDefaults = [OCMockObject mockForClass:[NSUserDefaults class]]; [[[mockDefaults expect] andReturn:@"Setting"] valueForKey:[OCMArg any]]; [[[mockController stub] andReturn:mockDefaults] userDefaults];
Static method testing • Through method swizzling void SwizzleClassMethod(Class c,
SEL orig, SEL new) { Method origMethod = class_getClassMethod(c, orig); Method newMethod = class_getClassMethod(c, new); c = object_getClass((id)c); if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); else method_exchangeImplementations(origMethod, newMethod); }
Normal conditions apply despite it’s iOS & Objective--C
Problems of „mobile devs” • Pushing code with failing tests
• Lot’s of hacking together • Weak knowledge of VCS tools - merge nightmares
Ending thoughts • Think first (twice), then code :) •
Tests should come first • Write the failing test, pass the test, refactor • Adequate tools can enhance your testing experience
Ending thoughts • Practice!
Thanks!
Questions