Your SlideShare is downloading. ×
iOS testing
Upcoming SlideShare
Loading in...5

Thanks for flagging this SlideShare!

Oops! An error has occurred.


Introducing the official SlideShare app

Stunning, full-screen experience for iPhone and Android

Text the download link to your phone

Standard text messaging rates apply

iOS testing


Published on

Testing in iOS using Kiwi and OCMock frameworks

Testing in iOS using Kiwi and OCMock frameworks

Published in: Technology

  • Be the first to comment

No Downloads
Total Views
On Slideshare
From Embeds
Number of Embeds
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

No notes for slide


  • 1. Testing in iOS10.01.2013 by Tomasz Janeczko
  • 2. About meTomasz Janeczko• iOS developer in Kainos• Enthusiast of business, electronics, Rails & Heroku• Organizer of first App Camp in UK and PL
  • 3. So let’s talk about testing.
  • 4. Why we test?
  • 5. So?
  • 6. • Reliability• Regression• Confidence (e.g. refactoring)
  • 7. Why not to test?
  • 8. Why not to test?• Heavy dependence on UI• Non-testable code• Bad framework
  • 9. How to address issues• Sample - downloading stuff from interwebz
  • 10. First faultWriting tests afterwriting code
  • 11. Separation of concerns
  • 12. Separation of concerns• Let’s separate out the UI code• Same for services interaction
  • 13. Demo of tests
  • 14. Writing testsMeet Kiwi and OCMock
  • 15. Kiwi• RSpec-like tests writing• Matchers• Cleaner and more self-descriptive code
  • 16. Kiwi describe(@"Tested class", ^{ context(@"When created", ^{ it(@"should not fail", ^{ [[theValue(0) should] equal:theValue(0)]; }); });});
  • 17. Kiwidescribe(@"Tested class", ^{ context(@"When created", ^{ it(@"should not fail", ^{ id viewController = [ViewController new]; [[viewController should]conformToProtocol:@protocol(UITableViewDelegate)]; }); });});
  • 18. Matchers [subject  shouldNotBeNil]• [subject  shouldBeNil]• [[subject  should]  beIdenticalTo:(id)anObject] - compares ids• [[subject  should]  equal:(id)anObject]• [[subject  should]  equal:(double)aValue  withDelta: (double)aDelta]• [[subject  should]  beWithin:(id)aDistance  of:(id)aValue]• [[subject  should]  beLessThan:(id)aValue]• etc.  etc.
  • 19. Compare to SenTesting Kit [[subject  should]  equal:anObject] compare  with STAssertEquals(subject,  anObject,  @”Should  be  equal”);
  • 20. OCMock• Mocking and stubbing library for iOS• Quite versatile• Makes use of NSProxy magic
  • 21. Sample workflows
  • 22. Classic calculator sample describe(@"Calculator",  ^{                context(@"with  the  numbers  60  and  5  entered",  ^{                RPNCalculator  *calculator  =  [[RPNCalculator  alloc]  init];                                beforeEach(^{                        [calculator  enter:60];                        [calculator  enter:5];                });                afterEach(^{                          [calculator  clear];                });                              it(@"returns  65  as  the  sum",  ^{                        [[theValue([calculator  add])  should]  equal:65  withDelta:.01];                });
  • 23. Test if calls dep methods 1. Create a mock dependency 2. Inject it 3. Call the method 4. Verify
  • 24. Test dependency// Create the tested object and mock to exchange part of the functionalityviewController = [ViewController new];mockController = [OCMockObject partialMockForObject:viewController];// Create the mock and change implementation to return our classid serviceMock = [OCMockObject mockForClass:[InterwebzService class]];[[[mockController stub] andReturn:serviceMock] service];// Define expectations[[serviceMock expect] downloadTweetsJSONWithSuccessBlock:[OCMArg any]];// Run the tested method[viewController tweetsButtonTapped:nil];// Verify - throws exception on failure[mockController verify];
  • 25. Testing one layer• Isolate dependencies• Objective-C is highly dynamic - we can change implementations of private methods or static methods• We can avoid IoC containers for testing
  • 26. Accessing private methods
  • 27. Accessing private methods @interface ViewController() - (void)startDownloadingTweets; @end ... [[mockController expect] startDownloadingTweets];
  • 28. Static method testing• Through separation to a method@interface ViewController()- (NSUserDefaults *)userDefaults; mockDefaults = [OCMockObject mockForClass:[NSUserDefaults class]];[[[mockDefaults expect] andReturn:@"Setting"] valueForKey:[OCMArg any]];[[[mockController stub] andReturn:mockDefaults] userDefaults];
  • 29. Static method testing• Through method swizzlingvoid  SwizzleClassMethod(Class  c,  SEL  orig,  SEL  new)  {        Method  origMethod  =  class_getClassMethod(c,  orig);        Method  newMethod  =  class_getClassMethod(c,  new);        c  =  object_getClass((id)c);        if(class_addMethod(c,  orig,  method_getImplementation(newMethod),  method_getTypeEncoding(newMethod)))                class_replaceMethod(c,  new,  method_getImplementation(origMethod),  method_getTypeEncoding(origMethod));        else                method_exchangeImplementations(origMethod,  newMethod);}
  • 30. Normal conditions apply despite it’s iOS & Objective--C
  • 31. Problems of „mobile devs” • Pushing code with failing tests • Lot’s of hacking together • Weak knowledge of VCS tools - merge nightmares
  • 32. Ending thoughts• Think first (twice), then code :)• Tests should come first• Write the failing test, pass the test, refactor• Adequate tools can enhance your testing experience
  • 33. Ending thoughts• Practice!
  • 34. Thanks!
  • 35. Questions