2. Why BDD? Why Kiwi?
Kiwi is BDD library for iOS, «RSpec» like, easy to
setup and use.
Kiwi Kiwi built on top of OCUnit
and tightly integrated with
Xcode!
OCUnit
3. Why BDD? Why Kiwi?
TDD - OCUnit : BDD - Kiwi :
@implementation testTests
describe(@"Team", ^{
context(@"when newly created", ^{
- (void)testThatTeamShouldHaveName
it(@"should have a name", ^{
{
id team = [Team team];
id team = [Team team];
[[team.name should] equal:@"Black Hawks"];
STAssertEqualObjects(team.name, @"Black
});
Hawks", @"Team shuld have a name");
});
});
}
1. Design 1. Nice structure
+
2. Test Logic 2. Better Assertions
4. Kiwi installation
• Old School way -
https://github.com/allending/Kiwi/wiki/Guide:-Up-and-Running-with-Kiwi
• Easy way - CocoaPods!!
//Podfile
platform :ios
target :KiwiUnitTest, :exclusive => true do
pod 'Kiwi'
end
5. Basic usage
• SPEC_BEGIN(ClassName) and SPEC_END -
SPEC_BEGIN(SpecName)
macros that expand to begin and end a KWSpec class
describe(@"ClassName", ^{ and group declaration.
context(@"a state the component is in", ^{
__block id variable = nil;
beforeAll(^{ // Occurs once
});
afterAll(^{ // Occurs once
});
beforeEach(^{ // Occurs before each enclosed "it"
variable = [MyClass instance];
});
afterEach(^{ // Occurs after each enclosed "it"
});
it(@"should do something", ^{
[[variable should] meetSomeExpectation];
});
context(@"inner context", ^{
xit(@"does another thing", ^{
});
pending(@"something unimplemented", ^{
});
})
});
});
SPEC_END
6. Basic usage
• SPEC_BEGIN(ClassName) and SPEC_END -
SPEC_BEGIN(SpecName)
macros that expand to begin and end a KWSpec class
describe(@"ClassName", ^{ and group declaration.
context(@"a state the component is in", ^{ • describe(aString, aBlock) - starts a context that can
__block id variable = nil; contain tests and nested contexts.
beforeAll(^{ // Occurs once
}); • context(aString, aBlock) - synonym for describe.
afterAll(^{ // Occurs once
});
beforeEach(^{ // Occurs before each enclosed "it"
variable = [MyClass instance];
});
afterEach(^{ // Occurs after each enclosed "it"
});
it(@"should do something", ^{
[[variable should] meetSomeExpectation];
});
context(@"inner context", ^{
xit(@"does another thing", ^{
});
pending(@"something unimplemented", ^{
});
})
});
});
SPEC_END
7. Basic usage
• SPEC_BEGIN(ClassName) and SPEC_END -
SPEC_BEGIN(SpecName)
macros that expand to begin and end a KWSpec class
describe(@"ClassName", ^{ and group declaration.
context(@"a state the component is in", ^{ • describe(aString, aBlock) - starts a context that can
__block id variable = nil; contain tests and nested contexts.
beforeAll(^{ // Occurs once
}); • context(aString, aBlock) - synonym for describe.
afterAll(^{ // Occurs once
}); • beforeAll(aBlock), afterAll(aBlock) - run once
beforeEach(^{ // Occurs before each enclosed "it"
before and after all the inner contexts and it blocks of
variable = [MyClass instance]; the context it is in.
});
afterEach(^{ // Occurs after each enclosed "it" • beforeEach(aBlock), afterEach(aBlock) - run before
}); and after every it block in all enclosed contexts.
it(@"should do something", ^{
[[variable should] meetSomeExpectation]; • it(aString, aBlock) - This is where actual actual
});
expectations on objects should go
context(@"inner context", ^{
xit(@"does another thing", ^{
});
pending(@"something unimplemented", ^{
});
})
});
});
SPEC_END
8. Basic usage
• SPEC_BEGIN(ClassName) and SPEC_END -
SPEC_BEGIN(SpecName)
macros that expand to begin and end a KWSpec class
describe(@"ClassName", ^{ and group declaration.
context(@"a state the component is in", ^{ • describe(aString, aBlock) - starts a context that can
__block id variable = nil; contain tests and nested contexts.
beforeAll(^{ // Occurs once
}); • context(aString, aBlock) - synonym for describe.
afterAll(^{ // Occurs once
}); • beforeAll(aBlock), afterAll(aBlock) - run once
beforeEach(^{ // Occurs before each enclosed "it"
before and after all the inner contexts and it blocks of
variable = [MyClass instance]; the context it is in.
});
afterEach(^{ // Occurs after each enclosed "it" • beforeEach(aBlock), afterEach(aBlock) - run before
}); and after every it block in all enclosed contexts.
it(@"should do something", ^{
[[variable should] meetSomeExpectation]; • it(aString, aBlock) - This is where actual actual
});
expectations on objects should go
context(@"inner context", ^{
xit(@"does another thing", ^{
});
• pending(aString, aBlock), xit(aString, aBlock) -
doesn't do anything other than log a pending message
pending(@"something unimplemented", ^{ to the output when run.
});
})
});
});
SPEC_END
10. Thanks!
• Kiwi repo - https://github.com/allending/Kiwi
• NSScreencast(episode about kiwi) - http://nsscreencast.com/
episodes/4-automated-testing-with-kiwi
• Test Driving iOS Development with Kiwi by Daniel H
Steinberg - iBooks Store Link