SlideShare a Scribd company logo
Testing in iOS
10.01.2013 by Tomasz Janeczko
About me
Tomasz Janeczko
• iOS developer in Kainos
• Enthusiast of business, electronics, Rails
  & Heroku
• Organizer of first App Camp in UK and
  PL
So let’s talk about testing.
Why we test?
iOS testing
So?
• Reliability

• Regression

• Confidence (e.g. refactoring)
Why not to test?
Why not to test?


• Heavy dependence on UI
• Non-testable code
• Bad framework
How to address issues


• Sample - downloading stuff from
  interwebz
First fault


Writing tests after
writing code
Separation of concerns
Separation of concerns


• Let’s separate out the UI code
• Same for services interaction
Demo of tests
Writing tests
Meet Kiwi and OCMock
Kiwi


• RSpec-like tests writing
• Matchers
• Cleaner and more self-descriptive code
Kiwi

  describe(@"Tested class", ^{

      context(@"When created", ^{

            it(@"should not fail", ^{
                [[theValue(0) should] equal:theValue(0)];
            });

      });

});
Kiwi

describe(@"Tested class", ^{

      context(@"When created", ^{

        it(@"should not fail", ^{
            id viewController = [ViewController new];
            [[viewController should]
conformToProtocol:@protocol(UITableViewDelegate)];
        });

      });

});
Matchers
  [subject	
  shouldNotBeNil]

• [subject	
  shouldBeNil]

• [[subject	
  should]	
  beIdenticalTo:(id)anObject] - compares id's

• [[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.
Compare to SenTesting Kit


               [[subject	
  should]	
  equal:anObject]


                            compare	
  with


   STAssertEquals(subject,	
  anObject,	
  @”Should	
  be	
  equal”);
OCMock


• Mocking and stubbing library for iOS
• Quite versatile
• Makes use of NSProxy magic
Sample workflows
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];
 	
  	
  	
  	
  	
  	
  	
  	
  });
Test if calls dep methods

 1. Create a mock dependency
 2. Inject it
 3. Call the method
 4. Verify
Test dependency

// Create the tested object and mock to exchange part of the functionality
viewController = [ViewController new];
mockController = [OCMockObject partialMockForObject:viewController];

// Create the mock and change implementation to return our class
id 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];
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
Accessing private methods
Accessing private methods

 @interface ViewController()

 - (void)startDownloadingTweets;

 @end



 ...
 [[mockController expect] startDownloadingTweets];
Static method testing

• Through separation to a method
@interface ViewController()

- (NSUserDefaults *)userDefaults;

@end

...

id mockDefaults = [OCMockObject mockForClass:[NSUserDefaults class]];

[[[mockDefaults expect] andReturn:@"Setting"] valueForKey:[OCMArg any]];

[[[mockController stub] andReturn:mockDefaults] userDefaults];
Static method testing

• Through method swizzling
void	
  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);
}
Normal conditions apply
   despite it’s iOS & Objective--C
Problems of „mobile devs”


 • Pushing code with failing tests
 • Lot’s of hacking together
 • Weak knowledge of VCS tools - merge
   nightmares
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
Ending thoughts



• Practice!
Thanks!
Questions

More Related Content

PDF
NestJS
PPTX
PDF
Testing React hooks with the new act function
PDF
An introduction to Angular2
PDF
PDF
React redux
PPTX
Workflow Foundation 4
PDF
Ngrx meta reducers
NestJS
Testing React hooks with the new act function
An introduction to Angular2
React redux
Workflow Foundation 4
Ngrx meta reducers

What's hot (19)

PDF
React&redux
ODP
Jquery- One slide completing all JQuery
ZIP
Barcamp Auckland Rails3 presentation
PDF
Angular js 2.0, ng poznań 20.11
PPTX
React with Redux
PDF
Redux vs Alt
PDF
Deep Dive into React Hooks
PDF
React state managmenet with Redux
PPTX
20131004 - Sq lite sample by Jax
PPTX
Кирилл Безпалый, .NET Developer, Ciklum
PPTX
ECS19 - Edin Kapic - WHO IS THAT? DEVELOPING AI-ASSISTED EMPLOYEE IMAGE TAGGING
PPTX
Javascript talk
PDF
Tdd iPhone For Dummies
PPTX
SOLID Principles
ODP
AngularJs Crash Course
PPTX
Extending C# with Roslyn and Code Aware Libraries
PPTX
Redux training
PDF
Getting Comfortable with JS Promises
React&redux
Jquery- One slide completing all JQuery
Barcamp Auckland Rails3 presentation
Angular js 2.0, ng poznań 20.11
React with Redux
Redux vs Alt
Deep Dive into React Hooks
React state managmenet with Redux
20131004 - Sq lite sample by Jax
Кирилл Безпалый, .NET Developer, Ciklum
ECS19 - Edin Kapic - WHO IS THAT? DEVELOPING AI-ASSISTED EMPLOYEE IMAGE TAGGING
Javascript talk
Tdd iPhone For Dummies
SOLID Principles
AngularJs Crash Course
Extending C# with Roslyn and Code Aware Libraries
Redux training
Getting Comfortable with JS Promises
Ad

Similar to iOS testing (20)

PDF
2013-01-10 iOS testing
PDF
iOS 101 - Xcode, Objective-C, iOS APIs
PDF
10 tips for a reusable architecture
PDF
Building stable testing by isolating network layer
PPTX
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
PPTX
Model View Presenter presentation
PDF
Describe's Full of It's
PPTX
Legacy Code Kata v3.0
PDF
谷歌 Scott-lessons learned in testability
PDF
Dsug 05 02-15 - ScalDI - lightweight DI in Scala
PDF
From mvc to viper
PPTX
Frontend training
PPTX
Web technologies-course 12.pptx
PDF
Testing for Pragmatic People
PDF
Intro to Unit Testing in AngularJS
PDF
Build Widgets
PDF
Breaking Dependencies to Allow Unit Testing
PDF
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
PPTX
Testing C# and ASP.net using Ruby
PPT
SQL Server 2005 CLR Integration
2013-01-10 iOS testing
iOS 101 - Xcode, Objective-C, iOS APIs
10 tips for a reusable architecture
Building stable testing by isolating network layer
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Model View Presenter presentation
Describe's Full of It's
Legacy Code Kata v3.0
谷歌 Scott-lessons learned in testability
Dsug 05 02-15 - ScalDI - lightweight DI in Scala
From mvc to viper
Frontend training
Web technologies-course 12.pptx
Testing for Pragmatic People
Intro to Unit Testing in AngularJS
Build Widgets
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies To Allow Unit Testing - Steve Smith | FalafelCON 2014
Testing C# and ASP.net using Ruby
SQL Server 2005 CLR Integration
Ad

Recently uploaded (20)

PPT
Teaching material agriculture food technology
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
KodekX | Application Modernization Development
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Machine learning based COVID-19 study performance prediction
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Encapsulation theory and applications.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Electronic commerce courselecture one. Pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
Teaching material agriculture food technology
NewMind AI Weekly Chronicles - August'25 Week I
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
KodekX | Application Modernization Development
Advanced methodologies resolving dimensionality complications for autism neur...
“AI and Expert System Decision Support & Business Intelligence Systems”
Machine learning based COVID-19 study performance prediction
20250228 LYD VKU AI Blended-Learning.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
MYSQL Presentation for SQL database connectivity
Digital-Transformation-Roadmap-for-Companies.pptx
Building Integrated photovoltaic BIPV_UPV.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Encapsulation theory and applications.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Unlocking AI with Model Context Protocol (MCP)
Chapter 3 Spatial Domain Image Processing.pdf
Electronic commerce courselecture one. Pdf
Review of recent advances in non-invasive hemoglobin estimation

iOS testing

  • 1. Testing in iOS 10.01.2013 by Tomasz Janeczko
  • 2. About me Tomasz 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.
  • 6. So?
  • 7. • Reliability • Regression • Confidence (e.g. refactoring)
  • 8. Why not to test?
  • 9. Why not to test? • Heavy dependence on UI • Non-testable code • Bad framework
  • 10. How to address issues • Sample - downloading stuff from interwebz
  • 11. First fault Writing tests after writing code
  • 13. Separation of concerns • Let’s separate out the UI code • Same for services interaction
  • 16. Kiwi • RSpec-like tests writing • Matchers • Cleaner and more self-descriptive code
  • 17. Kiwi describe(@"Tested class", ^{ context(@"When created", ^{ it(@"should not fail", ^{ [[theValue(0) should] equal:theValue(0)]; }); }); });
  • 18. Kiwi describe(@"Tested class", ^{ context(@"When created", ^{ it(@"should not fail", ^{ id viewController = [ViewController new]; [[viewController should] conformToProtocol:@protocol(UITableViewDelegate)]; }); }); });
  • 19. Matchers [subject  shouldNotBeNil] • [subject  shouldBeNil] • [[subject  should]  beIdenticalTo:(id)anObject] - compares id's • [[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.
  • 20. Compare to SenTesting Kit [[subject  should]  equal:anObject] compare  with STAssertEquals(subject,  anObject,  @”Should  be  equal”);
  • 21. OCMock • Mocking and stubbing library for iOS • Quite versatile • Makes use of NSProxy magic
  • 23. 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];                });
  • 24. Test if calls dep methods 1. Create a mock dependency 2. Inject it 3. Call the method 4. Verify
  • 25. Test dependency // Create the tested object and mock to exchange part of the functionality viewController = [ViewController new]; mockController = [OCMockObject partialMockForObject:viewController]; // Create the mock and change implementation to return our class id 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];
  • 26. 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
  • 28. Accessing private methods @interface ViewController() - (void)startDownloadingTweets; @end ... [[mockController expect] startDownloadingTweets];
  • 29. Static method testing • Through separation to a method @interface ViewController() - (NSUserDefaults *)userDefaults; @end ... id mockDefaults = [OCMockObject mockForClass:[NSUserDefaults class]]; [[[mockDefaults expect] andReturn:@"Setting"] valueForKey:[OCMArg any]]; [[[mockController stub] andReturn:mockDefaults] userDefaults];
  • 30. Static method testing • Through method swizzling void  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); }
  • 31. Normal conditions apply despite it’s iOS & Objective--C
  • 32. Problems of „mobile devs” • Pushing code with failing tests • Lot’s of hacking together • Weak knowledge of VCS tools - merge nightmares
  • 33. 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