iOS BDD with Kiwi
https://github.com/process255/insta-test
Sean Dougherty
sean@process255.com
@sdougherty
process255.com
s...
iOS engineer in Denver
writing iOS apps since 2010
web apps before that
Who am I?
iOS
Behavior Driven Development
with Kiwi
Insta-Test
https://github.com/process255/insta-test
An iOS App that displays the feed of popular
photos on Instagram.
Culture of testing.
Ruby On Rails
Objective-C
NO Culture of testing.
Ok, ALMOST no Culture of
testing.
Lots of Ruby developers are building iOS apps.
But... that is changing.
And they are bringing their tests with them.
But... that is changing.
What is TDD?
“Test driven development (TDD) is a software development
approach in which a test is written before writing t...
Why test our code?
“TDD encourages simple designs and inspires
confidence.”
Kent Beck, who is credited with having develope...
Why test our code?
Testing is another tool in our toolbox that helps us
build high quality software.
Why test our code?
A well maintained suite of tests gives
us confidence to refactor.
Why test our code?
Tests help new developers learn the code base and help
prevent new code from unknowingly breaking old c...
Why test our code?
Tests help us write better code.
Poorly written code is hard to test.Test driving our
code forces us to...
What is BDD?
Behavior Driven Development focuses and associates behavioral
specifications with each unit of software under ...
Apple’s OCUnit follows the traditional xUnit format.
Kiwi uses a specification format made popular by Ruby’s RSpec BDD libr...
Kiwi
OCUnit
it(@"should have 11 players", ^{
Team team = [Team team];
[[[team should] have:11] players];
});
- (void)testH...
Kiwi
What is it good at?
readable tests
testing asynchronous code
built in stubbing and mocking
partial mocking
What is it bad at?
helper methods
code reuse
clickable test failure messages
Kiwi specs read like a sentence.
The team, when newly created,
should have a name.
The team, when newly created,
should have 11 players.
describe(@"Team", ^{
context(@"when newly created", ^{
it(@"should have a name", ^{
Team team = [Team team];
[[team.name s...
describe(@"Subject", ^{
beforeAll(^{
...
});
afterAll(^{
...
});
beforeEach(^{
...
});
afterEach(^{
...
});
});
What do I want to test?
A pragmatic approach
Simple methods
Methods that take time (async)
RestKit’s Object Mapping
Testing Storyboards
How can I test it?
A pragmatic approach
Simple methods
- (NSString *)prettyTitle
context(@"-prettyTitle", ^{
it(@"should return 'Sean Dougherty: 1,000 likes", ^{
Instagram* instagram = [[Instagram alloc]...
Methods that take time (async)
- (void)loadPopularWithSuccess:failure:
it(@"should load 16 photos", ^{
__block RKMappingResult *result;
[service loadPopularWithSuccess:...)
{
result = mappingRe...
RestKit’s Object Mapping
specify(^{ [[mappingTest should] mapKeyPath:@"id"
toKeyPath:@"instagramID"
withValue:@"1"];});
Testing Storyboards
it(@"the tableView should exist", ^{
[vc.tableView shouldNotBeNil];
});
Mocking & Stubbing
__block InstaService *service;
beforeEach(^{
service = [KWMock mockForClass:[InstaService
class]];
});
Mocking
beforeEach(^{
Instagram *instagram = [[Instagram alloc] init];
instagram.thumbPath = @"thumb path";
instagram.prettyTitle ...
Testing Private Methods
and Private Properties
Use a class extension in your spec file
@interface InstaTableViewController ()
@property (nonatomic, copy) NSArray *instagr...
Demo Time
Other Options
OCUnit (built into Xcode)
Cedar
https://github.com/pivotal/cedar
Expecta
https://github.com/specta/expecta
S...
Resources
Insta-Test
https://github.com/process255/insta-test
Kiwi
https://github.com/allending/Kiwi
nsscreencast
http://n...
Attribution
Kiwi by Allen Ding
https://github.com/allending/Kiwi
AFNetworking by Matt Thompson and Scott
Raymond
https://g...
ThankYou
I os tdd-with-bdd
I os tdd-with-bdd
I os tdd-with-bdd
I os tdd-with-bdd
Upcoming SlideShare
Loading in …5
×

I os tdd-with-bdd

893 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
893
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
12
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

I os tdd-with-bdd

  1. 1. iOS BDD with Kiwi https://github.com/process255/insta-test Sean Dougherty sean@process255.com @sdougherty process255.com simpletomato.com
  2. 2. iOS engineer in Denver writing iOS apps since 2010 web apps before that Who am I?
  3. 3. iOS Behavior Driven Development with Kiwi
  4. 4. Insta-Test https://github.com/process255/insta-test An iOS App that displays the feed of popular photos on Instagram.
  5. 5. Culture of testing. Ruby On Rails
  6. 6. Objective-C NO Culture of testing.
  7. 7. Ok, ALMOST no Culture of testing.
  8. 8. Lots of Ruby developers are building iOS apps. But... that is changing.
  9. 9. And they are bringing their tests with them. But... that is changing.
  10. 10. What is TDD? “Test driven development (TDD) is a software development approach in which a test is written before writing the code.” http://www.techopedia.com/
  11. 11. Why test our code? “TDD encourages simple designs and inspires confidence.” Kent Beck, who is credited with having developed or 'rediscovered' the technique.
  12. 12. Why test our code? Testing is another tool in our toolbox that helps us build high quality software.
  13. 13. Why test our code? A well maintained suite of tests gives us confidence to refactor.
  14. 14. Why test our code? Tests help new developers learn the code base and help prevent new code from unknowingly breaking old code.
  15. 15. Why test our code? Tests help us write better code. Poorly written code is hard to test.Test driving our code forces us to do better.
  16. 16. What is BDD? Behavior Driven Development focuses and associates behavioral specifications with each unit of software under development. http://www.techopedia.com/
  17. 17. Apple’s OCUnit follows the traditional xUnit format. Kiwi uses a specification format made popular by Ruby’s RSpec BDD library. What is the difference?
  18. 18. Kiwi OCUnit it(@"should have 11 players", ^{ Team team = [Team team]; [[[team should] have:11] players]; }); - (void)testHasElevenPlayers { Team team = [Team team]; STAssertTrue(team.players == 11, @"should have 11 players"); }
  19. 19. Kiwi
  20. 20. What is it good at?
  21. 21. readable tests testing asynchronous code built in stubbing and mocking partial mocking
  22. 22. What is it bad at?
  23. 23. helper methods code reuse clickable test failure messages
  24. 24. Kiwi specs read like a sentence.
  25. 25. The team, when newly created, should have a name.
  26. 26. The team, when newly created, should have 11 players.
  27. 27. describe(@"Team", ^{ context(@"when newly created", ^{ it(@"should have a name", ^{ Team team = [Team team]; [[team.name should] equal:@"Avalanche"]; }); it(@"should have 11 players", ^{ Team team = [Team team]; [[[team should] have:11] players]; }); }); });
  28. 28. describe(@"Subject", ^{ beforeAll(^{ ... }); afterAll(^{ ... }); beforeEach(^{ ... }); afterEach(^{ ... }); });
  29. 29. What do I want to test? A pragmatic approach
  30. 30. Simple methods Methods that take time (async) RestKit’s Object Mapping Testing Storyboards
  31. 31. How can I test it? A pragmatic approach
  32. 32. Simple methods - (NSString *)prettyTitle
  33. 33. context(@"-prettyTitle", ^{ it(@"should return 'Sean Dougherty: 1,000 likes", ^{ Instagram* instagram = [[Instagram alloc] init]; instagram.fullName = @"Sean Dougherty"; instagram.likeCount = 1000; [[[instagram prettyTitle] should] equal:@"Sean Dougherty: 1,000 likes"]; }); });
  34. 34. Methods that take time (async) - (void)loadPopularWithSuccess:failure:
  35. 35. it(@"should load 16 photos", ^{ __block RKMappingResult *result; [service loadPopularWithSuccess:...) { result = mappingResult; } failure:nil]; [[expectFutureValue([result array]) shouldEventually] haveCountOf:16]; });
  36. 36. RestKit’s Object Mapping
  37. 37. specify(^{ [[mappingTest should] mapKeyPath:@"id" toKeyPath:@"instagramID" withValue:@"1"];});
  38. 38. Testing Storyboards
  39. 39. it(@"the tableView should exist", ^{ [vc.tableView shouldNotBeNil]; });
  40. 40. Mocking & Stubbing
  41. 41. __block InstaService *service; beforeEach(^{ service = [KWMock mockForClass:[InstaService class]]; }); Mocking
  42. 42. beforeEach(^{ Instagram *instagram = [[Instagram alloc] init]; instagram.thumbPath = @"thumb path"; instagram.prettyTitle = @"pretty title"; [vc stub:@selector(instagrams) andReturn:@[instagram]]; }); Stubbing
  43. 43. Testing Private Methods and Private Properties
  44. 44. Use a class extension in your spec file @interface InstaTableViewController () @property (nonatomic, copy) NSArray *instagrams; - (void)loadPopular; @end
  45. 45. Demo Time
  46. 46. Other Options OCUnit (built into Xcode) Cedar https://github.com/pivotal/cedar Expecta https://github.com/specta/expecta Specta https://github.com/specta/specta OCMock https://github.com/erikdoe/ocmock OCMockito https://github.com/jonreid/OCMockito Lots of others.
  47. 47. Resources Insta-Test https://github.com/process255/insta-test Kiwi https://github.com/allending/Kiwi nsscreencast http://nsscreencast.com/episodes/4-automated-testing-with-kiwi Test Driving iOS Development with Kiwi by Daniel H Steinberg https://itunes.apple.com/us/book/test-driving-ios-development/id502345143?mt=11
  48. 48. Attribution Kiwi by Allen Ding https://github.com/allending/Kiwi AFNetworking by Matt Thompson and Scott Raymond https://github.com/AFNetworking/ AFNetworking RestKit by Blake Watters https://github.com/RestKit/RestKit OHHTTPStubs by Olivier Halligon https://github.com/AliSoftware/OHHTTPStubs SDWebImage by Olivier Poitrey https://github.com/rs/SDWebImage SVProgressHUD by SamVermette https://github.com/samvermette/ SVProgressHUD CocoaPods by Eloy Durán http://cocoapods.org/
  49. 49. ThankYou

×