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
The Unit Testing of Objective-C
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
cockscomb
June 02, 2013
Programming
6
1.7k
The Unit Testing of Objective-C
Speaking at Cocoa Studies Kansai
cockscomb
June 02, 2013
Tweet
Share
More Decks by cockscomb
See All by cockscomb
jq at the Shortcuts
cockscomb
1
2k
GraphQL放談
cockscomb
4
2.1k
GraphQL Highway
cockscomb
28
8.7k
吉田を支える技術
cockscomb
0
2.5k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.4k
ユーザインターフェイスと非同期処理
cockscomb
5
2k
GUIアプリケーションの構造と設計
cockscomb
10
10k
イカリング2におけるシングルページアプリケーション
cockscomb
2
7.6k
あなたの知らない UIKit の世界 — UITableView に UITextView を置きたい
cockscomb
1
7.6k
Other Decks in Programming
See All in Programming
AI Agent の開発と運用を支える Durable Execution #AgentsInProd
izumin5210
7
2.3k
AI巻き込み型コードレビューのススメ
nealle
1
300
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
1k
IFSによる形状設計/デモシーンの魅力 @ 慶應大学SFC
gam0022
1
300
コマンドとリード間の連携に対する脅威分析フレームワーク
pandayumi
1
450
Patterns of Patterns
denyspoltorak
0
1.4k
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
Rust 製のコードエディタ “Zed” を使ってみた
nearme_tech
PRO
0
180
CSC307 Lecture 01
javiergs
PRO
0
690
並行開発のためのコードレビュー
miyukiw
0
170
ノイジーネイバー問題を解決する 公平なキューイング
occhi
0
100
そのAIレビュー、レビューしてますか? / Are you reviewing those AI reviews?
rkaga
6
4.6k
Featured
See All Featured
Become a Pro
speakerdeck
PRO
31
5.8k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
1
100
Faster Mobile Websites
deanohume
310
31k
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2k
Thoughts on Productivity
jonyablonski
74
5k
Exploring anti-patterns in Rails
aemeredith
2
250
Skip the Path - Find Your Career Trail
mkilby
0
56
A designer walks into a library…
pauljervisheath
210
24k
Navigating Team Friction
lara
192
16k
Leo the Paperboy
mayatellez
4
1.4k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
240
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
270
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