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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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.4k
jq at the Shortcuts
cockscomb
1
2.1k
GraphQL放談
cockscomb
4
2.2k
GraphQL Highway
cockscomb
28
8.8k
吉田を支える技術
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
仕様駆動開発の消費期限
watany
20
8.9k
Oxlintはいいぞ(続)
yug1224
1
430
使いながら育てる Claude Code — 開発フローの1コマンド化 × 繰り返し指摘の自動仕組み化
shiki_kakaku
1
1.9k
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
370
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
1.2k
Japan Community Day at Kubecon + CloudNativeCon Japan 2026: Learning Container Privilege Control by Building My Own Low-Level Container Runtime
ternbusty
1
170
不幸な GC
chencmd
0
720
freee が目指す データ マネジメント戦略 AI-Ready 時代を支える 攻めのガバナンスとは
freee
PRO
0
470
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
280
自動化したのに回らない テスト運用の壁―AI時代の品質責任と生産性
mfunaki
0
450
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
150
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.2k
Featured
See All Featured
The World Runs on Bad Software
bkeepers
PRO
72
12k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
280
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
480
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
400
Statistics for Hackers
jakevdp
799
230k
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Why Our Code Smells
bkeepers
PRO
340
58k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
520
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
10k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
950
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.9k
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