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
SwiftUI Viewの責務分離
elmetal
PRO
1
220
GAEログのコスト削減
mot_techtalk
0
120
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.1k
CNCF Project の作者が考えている OSS の運営
utam0k
6
710
Software Architecture
hschwentner
6
2.1k
Honoのおもしろいミドルウェアをみてみよう
yusukebe
1
200
Formの複雑さに立ち向かう
bmthd
1
810
密集、ドキュメントのコロケーション with AWS Lambda
satoshi256kbyte
0
190
Amazon ECS とマイクロサービスから考えるシステム構成
hiyanger
2
520
Grafana Cloudとソラカメ
devoc
0
140
AWS Organizations で実現する、 マルチ AWS アカウントのルートユーザー管理からの脱却
atpons
0
130
ソフトウェアエンジニアの成長
masuda220
PRO
10
920
Featured
See All Featured
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
320
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
31
2.1k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
366
25k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.7k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
Music & Morning Musume
bryan
46
6.3k
Facilitating Awesome Meetings
lara
51
6.2k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Building Applications with DynamoDB
mza
93
6.2k
Six Lessons from altMBA
skipperchong
27
3.6k
How to train your dragon (web standard)
notwaldorf
91
5.8k
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