BDD for iOS
by JMac
What is BDD?
“Behavior Driven Development”
Why BDD?
“Because we want to the way our system behaves,
not how it is implemented.”
–J.B. Rainsberger
“Integration tests are a scam.”
Sales Demo
How do I practice BDD for iOS?
“Cedar”
What is Cedar?
“a BDD-style Objective-C testing framework
with matchers and test doubles.”
How do I install Cedar?
“With CocoaPods”
What is CocoaPods?
“CocoaPods is a dependency manager for Swift
and Objective-C Cocoa projects, which automates
and simplifies the process of using 3rd-party
libraries in your projects.”
How do I use CocoaPods?
gem install cocoapods
pod init
The Podfile
platform :ios, '8.1'
target 'parked' do
pod 'Blindside'
pod 'Flurry-iOS-SDK'
end
target 'Specs' do
pod 'Blindside'
pod 'Cedar', git: 'https://github.com/pivotal/cedar.git'
pod 'PivotalCoreKit/Development', :git => 'https://github.com/
pivotal/PivotalCoreKit.git'
end
Project Type
Minimum SDK
Targets
Package/Pod
How do I install/update the pods?
pod install
Is that it?
“No.”
A few gotchas…
❖ You’ll want to close Xcode while managing Pods
❖ You’ll need to create any additional targets referenced in
the Podfile
❖ Once you install Pods, you need to open the Xcode
workspace
Setup Demo
The anatomy of a Spec file
❖ describe
❖ it
❖ beforeEach
❖ context
❖ and more (but not today)
describe
// group specs together
describe(@"the thing your testing", ^{
// test goes here code
});
it
// the test, expectation, or "spec"
it(@"should do the thing", ^{
expected should equal(actual);
});
beforeEach
// runs before each spec in the current block
beforeEach(^{
subject = [SomeViewController alloc]
init];
});
context
// group specs together based on state
context(@"when user is logged in", ^{
// test code
});
context(@"when user is logged out", ^{
// test code
});
Full Example
describe(@"tapping the save button", ^{
context(@"when the fields have input", ^{
it(@"should store the input in the database", ^{
// example
});
it(@"should call the delegate", ^{
// example
});
});
context(@"when the fields do not have input", ^{
it(@"should show an alert", ^{
// example
});
});
});
Matchers
❖ should and should_not
❖ equal
❖ be_nil, be_truthy, be_falsy, be_empty
❖ be_greater_than, be_less_than, etc
❖ be_same_instance_as, be_instance_of
Example
person.name should equal(@"JMac");
person.name should_not be_nil;
person.name.length should be_less_than(@5);
person should be_instance_of([Person class]);
person should be_same_instance_as(person);
Test Doubles (fakes)
❖ fake_for creates a test double of an object so its
methods can be stubbed
❖ nice_fake_for creates a test double of an object with
all its methods stubbed to return nil
Example
fakePerson = fake_for([Person class]);
fakePerson.name; // exception
niceFakePerson = nice_fake_for([Person class]);
niceFakePerson.name; // nil
niceFakePerson stub_method(@selector(name))
.and_return(@"JMac");
niceFakePerson.name; // @"JMac"
Code Demo
Resources
❖ CocoaPods
❖ Cedar
❖ Blindside
❖ Thrust
❖ Follow me on Twitter: @gonedark

BDD in iOS with Cedar