SlideShare a Scribd company logo
1 of 36
Download to read offline
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?
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

What's hot

Кирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, CiklumКирилл Безпалый, .NET Developer, Ciklum
Кирилл Безпалый, .NET Developer, Ciklum
Alina Vilk
 

What's hot (19)

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

Similar to iOS testing

谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability谷歌 Scott-lessons learned in testability
谷歌 Scott-lessons learned in testability
drewz lin
 
Testing for Pragmatic People
Testing for Pragmatic PeopleTesting for Pragmatic People
Testing for Pragmatic People
davismr
 
SQL Server 2005 CLR Integration
SQL Server 2005 CLR IntegrationSQL Server 2005 CLR Integration
SQL Server 2005 CLR Integration
webhostingguy
 

Similar to iOS testing (20)

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

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Recently uploaded (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 

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.
  • 5.
  • 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