Does it work?
I’m not here to convince you
Dry and easy to maintain
Better form of documentation
Protect
Tdd?
Tdd?

Test-driven development (TDD) is a
software development technique that relies
on the repetition of a very short deve...
Tdd?



first the developer writes a failing automated
test case that defines a desired improvement
or new function




  ...
Tdd?




then produces code to pass that test




                            http://en.wikipedia.org/wiki/Test-driven_dev...
Tdd?



and finally refactors the new code to
acceptable standard




                            http://en.wikipedia.org/...
Unit Tests?




A test is not a unit test if:


                       Michael Feathers
Unit Tests?




It talks to a database


                    Michael Feathers
Unit Tests?



It communicates across
the network

                     Michael Feathers
Unit Tests?




It touches the file system


                      Michael Feathers
Unit Tests?


You have to do things to
your environment to run
it (eg, change config files)

                       Michael ...
Unit Tests?



Tests that do this are
integration tests

                       Michael Feathers
Automatic Testing Lifecycle

   Steps
Fixture Setup
Automatic Testing Lifecycle

   Steps
Fixture Setup
                       SUT
Exercise SUT
Automatic Testing Lifecycle

   Steps
Fixture Setup
                       SUT
Exercise SUT

Verify Result
Automatic Testing Lifecycle

     Steps
  Fixture Setup

  Exercise SUT

  Verify Result

Fixture TearDown
What about iPhone Dev?
Unit Testing for iPhone
Former SenTestingKit



        OCUnit
TestCase definition


#import <SenTestingKit/SenTestingKit.h>
#import "RpnCalculator.h"

@interface RpnCalculatorTestCase ...
TestCase definition


#import <SenTestingKit/SenTestingKit.h>
#import "RpnCalculator.h"

@interface RpnCalculatorTestCase ...
TestCase Implementation

@implementation RpnCalculatorTestCase

-(void)setUp{
! rpnCalculator = [[RpnCalculator alloc]init...
Fixture Setup

@implementation RpnCalculatorTestCase

-(void)setUp{
! rpnCalculator = [[RpnCalculator alloc]init];
}

-(vo...
Exercise SUT

@implementation RpnCalculatorTestCase

-(void)setUp{
! rpnCalculator = [[RpnCalculator alloc]init];
}

-(voi...
Verify Result

@implementation RpnCalculatorTestCase

-(void)setUp{
! rpnCalculator = [[RpnCalculator alloc]init];
}

-(vo...
Fixture Teardown

@implementation RpnCalculatorTestCase

-(void)setUp{
! rpnCalculator = [[RpnCalculator alloc]init];
}

-...
Assertions

#define   STAssertNil(a1, description, ...)
#define   STAssertNotNil(a1, description, ...)
#define   STAssertT...
Xcode integration
Xcode integration
Presentation separate from logic
Presentation separate from logic
Presentation
Logic
Test
Xcode integration
Xcode integration
What if I have to access network...
Or I have correlated components..
Mock it!
Mock it!



[...] mock objects are
simulated objects that mimic
the behavior of real objects
in controlled ways
OCMock




http://www.mulle-kybernetik.com/software/OCMock/
Stubs vs Mocks
                     Mocks



Stubs
Stub



- (void)testReturnsStubbedReturnValue
{
!   mock = [OCMockObject mockForClass:[NSString class]];

    [[[mock stub...
Collaboration
                    SOAPMessage
                     XMLString

SOAPClient
   send

                    SOAP...
Collaboration
                    SOAPMessage
                     XMLString

SOAPClient
   send

                    SOAP...
Collaboration
                    SOAPMessage
                     XMLString

SOAPClient
   send

                    SOAP...
Mock

static const NSString * RawSOAPMessage = @"<ENV:evn
xmlns:ENV="http://www.w3.org/....

- (void)testClientShouldSendM...
Mockery

static const NSString * RawSOAPMessage = @"<ENV:evn
xmlns:ENV="http://www.w3.org/....

- (void)testClientShouldSe...
Exercise SUT

static const NSString * RawSOAPMessage = @"<ENV:evn
xmlns:ENV="http://www.w3.org/....

- (void)testClientSho...
Verify

static const NSString * RawSOAPMessage = @"<ENV:evn
xmlns:ENV="http://www.w3.org/....

- (void)testClientShouldSen...
What’s wrong with Unit Testing?
TEST
Tdd isn’t about tests, but about
 behaviors and specifications
A spoonful of syntactic sugar...
A spoonful of syntactic sugar...




       Behavior Driven
       Development
should insted of test
matchers instead of Assert
Bdd framework for iPhone Dev...
Bdd framework for iPhone Dev...
Spec Example
-(void)before {
! [SpecHelper loginAsAdmin];
}

-(void)itShouldAddAUser {
! [app.navigationButton touch];
! [...
Fixture Setup
-(void)before {
! [SpecHelper loginAsAdmin];
}

-(void)itShouldAddAUser {
! [app.navigationButton touch];
! ...
Exercise SUT
-(void)before {
! [SpecHelper loginAsAdmin];
}

-(void)itShouldAddAUser {
! [app.navigationButton touch];
! [...
Verify Result
-(void)before {
! [SpecHelper loginAsAdmin];
}

-(void)itShouldAddAUser {
! [app.navigationButton touch];
! ...
Fixture Teardown
-(void)before {
! [SpecHelper loginAsAdmin];
}

-(void)itShouldAddAUser {
! [app.navigationButton touch];...
Run On Simulator
No XCode Integration Yet
Conclusions
The Market Asks For Apps
More Apps...
More Apps...
More Apps!
Lot to Improve
Be Good Kids:
Test First!
Reclame




http://milano-xpug.pbworks.com/
http://tech.groups.yahoo.com/group/milano-xpug/
Questions?
Tdd iPhone For Dummies
Tdd iPhone For Dummies
Tdd iPhone For Dummies
Upcoming SlideShare
Loading in...5
×

Tdd iPhone For Dummies

3,414

Published on

Everything you must know to start develop iPhone Applications in safe and fun way!

Published in: Technology
3 Comments
8 Likes
Statistics
Notes
  • really interesting and useful
    the images used in the presentation are very funny
    thank you!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Grazie mille!
    Ho cercato di essere leggero e stuzzicare la curiosità in modo da approfondire un tema molto importante.
    Sono felice che entrambi gli scopi siano stati raggiunti :-)
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Ottima presentazione. Complimenti anche per l'esposizione fluida e per niente noisa.
    Lo speech ha sicuramente stuzzicato la mia attenzione con spunti di riflessione davvero interessanti, c'è molto da crescere nell'ambito TDD per Objective-c e a maggior ragione per iPhone.
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
3,414
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
71
Comments
3
Likes
8
Embeds 0
No embeds

No notes for slide

Tdd iPhone For Dummies

  1. 1. Does it work?
  2. 2. I’m not here to convince you
  3. 3. Dry and easy to maintain
  4. 4. Better form of documentation
  5. 5. Protect
  6. 6. Tdd?
  7. 7. Tdd? Test-driven development (TDD) is a software development technique that relies on the repetition of a very short development cycle http://en.wikipedia.org/wiki/Test-driven_development
  8. 8. Tdd? first the developer writes a failing automated test case that defines a desired improvement or new function http://en.wikipedia.org/wiki/Test-driven_development
  9. 9. Tdd? then produces code to pass that test http://en.wikipedia.org/wiki/Test-driven_development
  10. 10. Tdd? and finally refactors the new code to acceptable standard http://en.wikipedia.org/wiki/Test-driven_development
  11. 11. Unit Tests? A test is not a unit test if: Michael Feathers
  12. 12. Unit Tests? It talks to a database Michael Feathers
  13. 13. Unit Tests? It communicates across the network Michael Feathers
  14. 14. Unit Tests? It touches the file system Michael Feathers
  15. 15. Unit Tests? You have to do things to your environment to run it (eg, change config files) Michael Feathers
  16. 16. Unit Tests? Tests that do this are integration tests Michael Feathers
  17. 17. Automatic Testing Lifecycle Steps Fixture Setup
  18. 18. Automatic Testing Lifecycle Steps Fixture Setup SUT Exercise SUT
  19. 19. Automatic Testing Lifecycle Steps Fixture Setup SUT Exercise SUT Verify Result
  20. 20. Automatic Testing Lifecycle Steps Fixture Setup Exercise SUT Verify Result Fixture TearDown
  21. 21. What about iPhone Dev?
  22. 22. Unit Testing for iPhone
  23. 23. Former SenTestingKit OCUnit
  24. 24. TestCase definition #import <SenTestingKit/SenTestingKit.h> #import "RpnCalculator.h" @interface RpnCalculatorTestCase : SenTestCase { ! RpnCalculator* rpnCalculator; } @end
  25. 25. TestCase definition #import <SenTestingKit/SenTestingKit.h> #import "RpnCalculator.h" @interface RpnCalculatorTestCase : SenTestCase { ! RpnCalculator* rpnCalculator; } @end
  26. 26. TestCase Implementation @implementation RpnCalculatorTestCase -(void)setUp{ ! rpnCalculator = [[RpnCalculator alloc]init]; } -(void)testShouldDisplayTwoNumbersWhenNumbersAreSeparatedByEnter{ ! [rpnCalculator put:@"1"]; ! [rpnCalculator put:@"enter"]; ! [rpnCalculator put:@"2"];! ! ! STAssertEqualObjects(@"1n2",rpnCalculator.display,nil); } -(void)tearDown{ [rpnCalculator release]; }
  27. 27. Fixture Setup @implementation RpnCalculatorTestCase -(void)setUp{ ! rpnCalculator = [[RpnCalculator alloc]init]; } -(void)testShouldDisplayTwoNumbersWhenNumbersAreSeparatedByEnter{ ! [rpnCalculator put:@"1"]; ! [rpnCalculator put:@"enter"]; ! [rpnCalculator put:@"2"];! ! ! STAssertEqualObjects(@"1n2",rpnCalculator.display,nil); } -(void)tearDown{ [rpnCalculator release]; }
  28. 28. Exercise SUT @implementation RpnCalculatorTestCase -(void)setUp{ ! rpnCalculator = [[RpnCalculator alloc]init]; } -(void)testShouldDisplayTwoNumbersWhenNumbersAreSeparatedByEnter{ ! [rpnCalculator put:@"1"]; ! [rpnCalculator put:@"enter"]; ! [rpnCalculator put:@"2"];! ! ! STAssertEqualObjects(@"1n2",rpnCalculator.display,nil); } -(void)tearDown{ [rpnCalculator release]; }
  29. 29. Verify Result @implementation RpnCalculatorTestCase -(void)setUp{ ! rpnCalculator = [[RpnCalculator alloc]init]; } -(void)testShouldDisplayTwoNumbersWhenNumbersAreSeparatedByEnter{ ! [rpnCalculator put:@"1"]; ! [rpnCalculator put:@"enter"]; ! [rpnCalculator put:@"2"];! ! ! STAssertEqualObjects(@"1n2",rpnCalculator.display,nil); } -(void)tearDown{ [rpnCalculator release]; }
  30. 30. Fixture Teardown @implementation RpnCalculatorTestCase -(void)setUp{ ! rpnCalculator = [[RpnCalculator alloc]init]; } -(void)testShouldDisplayTwoNumbersWhenNumbersAreSeparatedByEnter{ ! [rpnCalculator put:@"1"]; ! [rpnCalculator put:@"enter"]; ! [rpnCalculator put:@"2"];! ! ! STAssertEqualObjects(@"1n2",rpnCalculator.display,nil); } -(void)tearDown{ [rpnCalculator release]; }
  31. 31. Assertions #define STAssertNil(a1, description, ...) #define STAssertNotNil(a1, description, ...) #define STAssertTrue(expression, description, ...) #define STAssertFalse(expression, description, ...) #define STAssertEqualObjects(a1, a2, description, ...) #define STAssertEquals(a1, a2, description, ...) #define STFail(description, ...) #define STAssertTrueNoThrow(expression, description, ...) #define STAssertFalseNoThrow(expression, description, ...) //....
  32. 32. Xcode integration
  33. 33. Xcode integration
  34. 34. Presentation separate from logic
  35. 35. Presentation separate from logic
  36. 36. Presentation
  37. 37. Logic
  38. 38. Test
  39. 39. Xcode integration
  40. 40. Xcode integration
  41. 41. What if I have to access network...
  42. 42. Or I have correlated components..
  43. 43. Mock it!
  44. 44. Mock it! [...] mock objects are simulated objects that mimic the behavior of real objects in controlled ways
  45. 45. OCMock http://www.mulle-kybernetik.com/software/OCMock/
  46. 46. Stubs vs Mocks Mocks Stubs
  47. 47. Stub - (void)testReturnsStubbedReturnValue { ! mock = [OCMockObject mockForClass:[NSString class]]; [[[mock stub] andReturn:@"megamock"] lowercaseString]; id returnValue = [mock lowercaseString]; ! STAssertEqualObjects(@"megamock", returnValue, nil); }
  48. 48. Collaboration SOAPMessage XMLString SOAPClient send SOAPChannel post
  49. 49. Collaboration SOAPMessage XMLString SOAPClient send SOAPChannel post
  50. 50. Collaboration SOAPMessage XMLString SOAPClient send SOAPChannel post
  51. 51. Mock static const NSString * RawSOAPMessage = @"<ENV:evn xmlns:ENV="http://www.w3.org/.... - (void)testClientShouldSendMessage{ ! id msgMock = [OCMockObject mockForClass:[SOAPMessage class]]; ! [[[msgMock expect] andReturn:RawSOAPMessage] XMLString]; ! id channelMock = [OCMockObject mockForClass:[SOAPChannel class]]; ! [[[channelMock expect] andReturn:TRUE] send]; ! SOAPClient *client = [SOAPClient initWith:channelMock]; ! ! [client sendMessage:msgMock]; ! [msgMock verify]; ! [channelMock verify]; }
  52. 52. Mockery static const NSString * RawSOAPMessage = @"<ENV:evn xmlns:ENV="http://www.w3.org/.... - (void)testClientShouldSendMessage{ ! id msgMock = [OCMockObject mockForClass:[SOAPMessage class]]; ! [[[msgMock expect] andReturn:RawSOAPMessage] XMLString]; ! id channelMock = [OCMockObject mockForClass:[SOAPChannel class]]; ! [[[channelMock expect] andReturn:TRUE] send]; ! SOAPClient *client = [SOAPClient initWith:channelMock]; ! ! [client sendMessage:msgMock]; ! [msgMock verify]; ! [channelMock verify]; }
  53. 53. Exercise SUT static const NSString * RawSOAPMessage = @"<ENV:evn xmlns:ENV="http://www.w3.org/.... - (void)testClientShouldSendMessage{ ! id msgMock = [OCMockObject mockForClass:[SOAPMessage class]]; ! [[[msgMock expect] andReturn:RawSOAPMessage] XMLString]; ! id channelMock = [OCMockObject mockForClass:[SOAPChannel class]]; ! [[[channelMock expect] andReturn:TRUE] send]; ! SOAPClient *client = [SOAPClient initWith:channelMock]; ! ! [client sendMessage:msgMock]; ! [msgMock verify]; ! [channelMock verify]; }
  54. 54. Verify static const NSString * RawSOAPMessage = @"<ENV:evn xmlns:ENV="http://www.w3.org/.... - (void)testClientShouldSendMessage{ ! id msgMock = [OCMockObject mockForClass:[SOAPMessage class]]; ! [[[msgMock expect] andReturn:RawSOAPMessage] XMLString]; ! id channelMock = [OCMockObject mockForClass:[SOAPChannel class]]; ! [[[channelMock expect] andReturn:TRUE] send]; ! SOAPClient *client = [SOAPClient initWith:channelMock]; ! ! [client sendMessage:msgMock]; ! [msgMock verify]; ! [channelMock verify]; }
  55. 55. What’s wrong with Unit Testing?
  56. 56. TEST
  57. 57. Tdd isn’t about tests, but about behaviors and specifications
  58. 58. A spoonful of syntactic sugar...
  59. 59. A spoonful of syntactic sugar... Behavior Driven Development
  60. 60. should insted of test matchers instead of Assert
  61. 61. Bdd framework for iPhone Dev...
  62. 62. Bdd framework for iPhone Dev...
  63. 63. Spec Example -(void)before { ! [SpecHelper loginAsAdmin]; } -(void)itShouldAddAUser { ! [app.navigationButton touch]; ! [[app.textField.with placeholder:@"First Name"] setText:@"Brian"]; ! [[app.textField.with placeholder:@"Last Name"] setText:@"Knorr"]; ! [[app.textField.with placeholder:@"Email"] setText:@"b@g.com"]; ! [[app.textField placeholder:@"Username"] setText:@"bkuser"]; ! [[app.textField placeholder:@"Password"] setText:@"test"]; ! [[app.textField placeholder:@"Confirm"] setText:@"test"]; ! [[app.navigationButton.label text:@"Save"] touch]; ! [app timeout:1].alertView.should.not.exist; ! [[app.tableView.label text:@"Brian Knorr"] should].exist; } -(void)after { ! [SpecHelper logout]; }
  64. 64. Fixture Setup -(void)before { ! [SpecHelper loginAsAdmin]; } -(void)itShouldAddAUser { ! [app.navigationButton touch]; ! [[app.textField.with placeholder:@"First Name"] setText:@"Brian"]; ! [[app.textField.with placeholder:@"Last Name"] setText:@"Knorr"]; ! [[app.textField.with placeholder:@"Email"] setText:@"b@g.com"]; ! [[app.textField placeholder:@"Username"] setText:@"bkuser"]; ! [[app.textField placeholder:@"Password"] setText:@"test"]; ! [[app.textField placeholder:@"Confirm"] setText:@"test"]; ! [[app.navigationButton.label text:@"Save"] touch]; ! [app timeout:1].alertView.should.not.exist; ! [[app.tableView.label text:@"Brian Knorr"] should].exist; } -(void)after { ! [SpecHelper logout]; }
  65. 65. Exercise SUT -(void)before { ! [SpecHelper loginAsAdmin]; } -(void)itShouldAddAUser { ! [app.navigationButton touch]; ! [[app.textField.with placeholder:@"First Name"] setText:@"Brian"]; ! [[app.textField.with placeholder:@"Last Name"] setText:@"Knorr"]; ! [[app.textField.with placeholder:@"Email"] setText:@"b@g.com"]; ! [[app.textField placeholder:@"Username"] setText:@"bkuser"]; ! [[app.textField placeholder:@"Password"] setText:@"test"]; ! [[app.textField placeholder:@"Confirm"] setText:@"test"]; ! [[app.navigationButton.label text:@"Save"] touch]; ! [app timeout:1].alertView.should.not.exist; ! [[app.tableView.label text:@"Brian Knorr"] should].exist; } -(void)after { ! [SpecHelper logout]; }
  66. 66. Verify Result -(void)before { ! [SpecHelper loginAsAdmin]; } -(void)itShouldAddAUser { ! [app.navigationButton touch]; ! [[app.textField.with placeholder:@"First Name"] setText:@"Brian"]; ! [[app.textField.with placeholder:@"Last Name"] setText:@"Knorr"]; ! [[app.textField.with placeholder:@"Email"] setText:@"b@g.com"]; ! [[app.textField placeholder:@"Username"] setText:@"bkuser"]; ! [[app.textField placeholder:@"Password"] setText:@"test"]; ! [[app.textField placeholder:@"Confirm"] setText:@"test"]; ! [[app.navigationButton.label text:@"Save"] touch]; ! [app timeout:1].alertView.should.not.exist; ! [[app.tableView.label text:@"Brian Knorr"] should].exist; } -(void)after { ! [SpecHelper logout]; }
  67. 67. Fixture Teardown -(void)before { ! [SpecHelper loginAsAdmin]; } -(void)itShouldAddAUser { ! [app.navigationButton touch]; ! [[app.textField.with placeholder:@"First Name"] setText:@"Brian"]; ! [[app.textField.with placeholder:@"Last Name"] setText:@"Knorr"]; ! [[app.textField.with placeholder:@"Email"] setText:@"b@g.com"]; ! [[app.textField placeholder:@"Username"] setText:@"bkuser"]; ! [[app.textField placeholder:@"Password"] setText:@"test"]; ! [[app.textField placeholder:@"Confirm"] setText:@"test"]; ! [[app.navigationButton.label text:@"Save"] touch]; ! [app timeout:1].alertView.should.not.exist; ! [[app.tableView.label text:@"Brian Knorr"] should].exist; } -(void)after { ! [SpecHelper logout]; }
  68. 68. Run On Simulator
  69. 69. No XCode Integration Yet
  70. 70. Conclusions
  71. 71. The Market Asks For Apps
  72. 72. More Apps...
  73. 73. More Apps...
  74. 74. More Apps!
  75. 75. Lot to Improve
  76. 76. Be Good Kids:
  77. 77. Test First!
  78. 78. Reclame http://milano-xpug.pbworks.com/ http://tech.groups.yahoo.com/group/milano-xpug/
  79. 79. Questions?
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×