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
The Unit Testing of Objective-C
Search
cockscomb
June 02, 2013
Programming
1.7k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
The Unit Testing of Objective-C
Speaking at Cocoa Studies Kansai
cockscomb
June 02, 2013
More Decks by cockscomb
See All by cockscomb
はてなアカウント基盤 State of the Union
cockscomb
1
1.5k
jq at the Shortcuts
cockscomb
1
2.1k
GraphQL放談
cockscomb
4
2.2k
GraphQL Highway
cockscomb
28
8.9k
吉田を支える技術
cockscomb
0
2.6k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.5k
ユーザインターフェイスと非同期処理
cockscomb
5
2.1k
GUIアプリケーションの構造と設計
cockscomb
10
10k
イカリング2におけるシングルページアプリケーション
cockscomb
2
7.7k
Other Decks in Programming
See All in Programming
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
760
AIエージェント時代のコードレビューを設計する
nogu66
6
2.7k
The Good Stuff, Not the Slop: Engineering High-Quality Android Apps with Modern AI Tooling
danybony
1
250
[GoCon2026] When Goroutines Are Not Enough: Runtime Locality in High-Throughput Go
takehaya
6
2.1k
AI に Inclusive UI を書かせよう — Design Rules Skill で Compose UI を作り直す
theoriatec2024
1
480
巨大モノリシックアプリ モダン化大作戦
ktcryomm
0
970
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
310
Jetpack Compose メカニズム
skydoves
0
310
AI × TiDD / 2026.09.05 Redmine 大阪
tokudiro
1
140
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
220
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
240
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
1
450
Featured
See All Featured
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
4
640
Making the Leap to Tech Lead
cromwellryan
135
10k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
57k
What's in a price? How to price your products and services
michaelherold
247
13k
4 Signs Your Business is Dying
shpigford
187
23k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
320
Digital Ethics as a Driver of Design Innovation
axbom
PRO
1
420
The World Runs on Bad Software
bkeepers
PRO
72
12k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Transcript
The Unit Testing of Objective-C [[codes should] beTested];
cockscomb
None
Hatena Blog
KyotoCamera
The Unit Testing of Objective-C [[codes should] beTested];
Unit Test Frameworks
•OCUnit (SenTestingKit) •GHUnit •Kiwi
• Built-in • Easy to setup • Just select “Include
Unit Tests” when creating projects • Crazily easy executing • ⌘ + U™ OCUnit
#import <SenTestingKit/SenTestingKit.h> @interface Tests : SenTestCase @end @implementation Tests -
(void)setUp { [super setUp]; } - (void)tearDown { [super tearDown]; } - (void)testExample { STFail(@"Unit tests are not implemented yet in Tests"); } @end
• Very simple • But… wait, • QUESTION: How to
test asynchronous process, like delegate and blocks? •ANSWER: Do `while` •or use great third-party plug-ins
• Powerful features • Like OCUnit • Supporting asynchronous process
• And, powerful features GHUnit
#import <GHUnitIOS/GHUnit.h> @interface ExampleTest : GHTestCase { } @end @implementation
ExampleTest - (void)setUpClass { } - (void)tearDownClass { } - (void)setUp { } - (void)tearDown { } - (void)testFoo { NSString *a = @"foo"; GHAssertNotNULL(a, nil); NSString *b = @"bar"; GHAssertEqualObjects(a, b, @"A custom error message. a should be equal to: %@.", b); } @end
@interface ExampleAsyncTest : GHAsyncTestCase { } @end @implementation ExampleAsyncTest -
(void)testURLConnection { [self prepare]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http:// www.google.com"]]; NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES]; [self waitForStatus:kGHUnitWaitStatusSuccess timeout:10.0]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testURLConnection)]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [self notify:kGHUnitWaitStatusFailure forSelector:@selector(testURLConnection)]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { GHTestLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]); } @end
are shown in iOS Simulator Testing Results
Kiwi • BDD for iOS • Simple to setup and
use • Supporting CocoaPods • Supported by AppCode 2.0 • ⌘ + U™, OMG
describe(@"Team", ^{ context(@"when newly created", ^{ it(@"should have a name",
^{ id team = [Team team]; [[team.name should] equal:@"Black Hawks"]; }); it(@"should have 11 players", ^{ id team = [Team team]; [[[team should] have:11] players]; }); }); });
#import "Kiwi.h" SPEC_BEGIN(SpecName) describe(@"ClassName", ^{ context(@"a state the component is
in", ^{ __block id variable = nil; beforeAll(^{}); afterAll(^{}); beforeEach(^{ variable = [MyClass instance]; }); afterEach(^{}); it(@"should do something", ^{ [[variable should] meetSomeExpectation]; }); specify(^{ [variable shouldNotBeNil] }); pending(@"something unimplemented", ^{}); }); }); SPEC_END
id car = [Car car]; [car shouldNotBeNil]; [[car should] beKindOfClass:[Car
class]]; [[car shouldNot] conformToProtocol:@protocol(FlyingMachine)]; [[[car should] have:4] wheels]; [[theValue(car.speed) should] equal:theValue(42.0f)]; [[[car should] receive] changeToGear:3];
id carMock = [Car mock]; [[carMock should] beMemberOfClass:[Car class]]; [[carMock
should] receive:@selector(currentGear) andReturn:theValue(3)]; [[theValue(carMock.currentGear) should] equal:theValue(3)]; id carNullMock = [Car nullMock]; [[theValue(carNullMock.currentGear) should] equal:theValue(0)]; [carNullMock applyBrakes]; id flyerMock = [KWMock mockForProtocol: @protocol(FlyingMachine)]; [[flyerMock should] conformToProtocol: @protocol(FlyingMachine)]; [flyerMock stub:@selector(dragCoefficient) andReturn:theValue(17.0f)]; id flyerNullMock = [KWMock nullMockForProtocol: @protocol(FlyingMachine)]; [flyerNullMock takeOff]; [subject stub:(SEL)aSelector];
context(@"Fetching service data", ^{ it(@"should receive data within one second",
^{ [[LRResty client] get:@"http://www.example.com" withBlock: ^(LRRestyResponse* r) { NSLog(@"That's it! %@", [r asString]); fetchedData = [r asString]; }]; [[expectFutureValue(fetchedData) shouldEventually] beNonNil]; }); });
• Most powerful • Including mocks and stubs • Characteristic
style using blocks • Simple and easy • Highly recommended
Network Stubs
Nocilla • HTTP stubbing for iOS • Easy DSL interface
• NSURLProtocol • Supporting AFNetworking
stubRequest(@"POST", @"https://api.example.com/dogs.json"). withHeaders(@{ @"Accept": @"application/json", @"X-CUSTOM-HEADER": @"abcf2fbc6abgf" }). withBody(@"{\"name\":\"foo\"}"). andReturn(201).
withHeaders(@{ @"Content-Type": @"application/json" }). withBody(@"{\"ok\":true}");
Integration Test
UIAutomation • Built-in • Instruments • JavaScript interface • UIA*
objects
var editButton = UIATarget. localTarget(). frontMostApp(). mainWindow(). buttons()[0]; editButton.tap();
• Record your operation using Instruments • Executable from command-line
• tuneup.js • Assertions • Runner script
• There’s so many solutions for TDD Cocoa • Make
decision what’s frameworks to use • and I chosen Kiwi, Nocilla, UIAutomation • Test, Test, Test… Overall
None