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
cockscomb
June 02, 2013
Programming
6
1.6k
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
1.8k
GraphQL放談
cockscomb
4
1.9k
GraphQL Highway
cockscomb
28
8.3k
吉田を支える技術
cockscomb
0
2.2k
コーポレートサイトを静的化してAmplify Consoleにデプロイする
cockscomb
0
3.4k
ユーザインターフェイスと非同期処理
cockscomb
5
1.8k
GUIアプリケーションの構造と設計
cockscomb
10
10k
イカリング2におけるシングルページアプリケーション
cockscomb
2
7.4k
あなたの知らない UIKit の世界 — UITableView に UITextView を置きたい
cockscomb
1
7.4k
Other Decks in Programming
See All in Programming
ISUCON14公式反省会LT: 社内ISUCONの話
astj
PRO
0
180
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
2
490
AWS Organizations で実現する、 マルチ AWS アカウントのルートユーザー管理からの脱却
atpons
0
130
DROBEの生成AI活用事例 with AWS
ippey
0
130
最近のVS Codeで気になるニュース 2025/01
74th
1
250
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
10
1.8k
[JAWS-UG横浜 #79] re:Invent 2024 の DB アップデートは Multi-Region!
maroon1st
1
140
富山発の個人開発サービスで日本中の学校の業務を改善した話
krpk1900
4
370
SwiftUIで単方向アーキテクチャを導入して得られた成果
takuyaosawa
0
260
Writing documentation can be fun with plugin system
okuramasafumi
0
120
ARA Ansible for the teams
kksat
0
150
2024年のkintone API振り返りと2025年 / kintone API look back in 2024
tasshi
0
210
Featured
See All Featured
It's Worth the Effort
3n
184
28k
Documentation Writing (for coders)
carmenintech
67
4.6k
RailsConf 2023
tenderlove
29
1k
Docker and Python
trallard
44
3.3k
What's in a price? How to price your products and services
michaelherold
244
12k
Music & Morning Musume
bryan
46
6.3k
Six Lessons from altMBA
skipperchong
27
3.6k
YesSQL, Process and Tooling at Scale
rocio
171
14k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Rails Girls Zürich Keynote
gr2m
94
13k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
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