A light-weight TDD / BDD framework for Objective-C & Cocoa.
- RSpec-like BDD DSL
- Super quick and easy to set up
- Runs on top of OCUnit
- Excellent Xcode integration
Use CocoaPods
dependency 'Specta', '~> 0.1.7'
# dependency 'Expecta', '~> 0.2.0' # expecta matchers
# dependency 'OCHamcrest', '~> 1.7' # hamcrest matchers
# dependency 'OCMock', '~> 2.0.1' # OCMock
# dependency 'LRMocky', '~> 0.9.1' # LRMocky
or
- Clone from Github.
- Run
rake
in project root to build. - Add a "Cocoa/Cocoa Touch Unit Testing Bundle" target if you don't already have one.
- Copy and add all header files in
products
folder to the Test target in your Xcode project. - For OS X projects, copy and add
libSpecta-macosx.a
inproducts
folder to the Test target in your Xcode project.
For iOS projects, copy and addlibSpecta-ios-universal.a
inproducts
folder to the Test target in your Xcode project. - Add the following to your test code.
#import "Specta.h"
Standard OCUnit matchers such as STAssertEqualObjects
and STAssertNil
work, but you probably want to add a nicer matcher framework - Expecta to your setup. Or if you really prefer, OCHamcrest works fine too. Also, add a mocking framework: OCMock.
#import "Specta.h"
SharedExamplesBegin(MySharedExamples)
// Global shared examples are shared across all spec files.
sharedExamplesFor(@"a shared behavior", ^(NSDictionary *data) {
it(@"should do some stuff", ^{
// ...
});
});
SharedExamplesEnd
SpecBegin(Thing)
describe(@"Thing", ^{
sharedExamplesFor(@"another shared behavior", ^(NSDictionary *data) {
// Locally defined shared examples can override global shared examples within its scope.
});
beforeAll(^{
// This is run once and only once before all of the examples
// in this group and before any beforeEach blocks.
});
beforeEach(^{
// This is run before each example.
});
it(@"should do stuff", ^{
// This is an example block. Place your assertions here.
});
it(@"should do some stuff asynchronously", ^AsyncBlock {
// Async example blocks need to invoke done() callback.
done();
});
itShouldBehaveLike(@"a shared behavior", [NSDictionary dictionaryWithObjectsAndKeys:@"obj", @"key", nil]);
itShouldBehaveLike(@"another shared behavior", ^{
// Use a block that returns a dictionary if you need the context to be evaluated lazily,
// e.g. to use an object prepared in a beforeEach block.
return [NSDictionary dictionaryWithObjectsAndKeys:@"obj", @"key", nil];
});
describe(@"Nested examples", ^{
it(@"should do even more stuff", ^{
// ...
});
});
pending(@"pending example");
pending(@"another pending example", ^{
// ...
});
afterEach(^{
// This is run after each example.
});
afterAll(^{
// This is run once and only once after all of the examples
// in this group and after any afterEach blocks.
});
});
SpecEnd
beforeEach
andafterEach
are also aliased asbefore
andafter
respectively.describe
is also aliased ascontext
.it
is also aliased asexample
andspecify
.itShouldBehaveLike
is also aliased asitBehavesLike
.- Use
pending
or prependx
todescribe
,context
,example
,it
, andspecify
to mark examples or groups as pending. - Use
^AsyncBlock
as shown in the example above to make examples wait for completion.done()
callback needs to be invoked to let Specta know that your test is complete. (before|after)(Each/All)
also accept^AsyncBlock
s.- Do
#define SPT_CEDAR_SYNTAX
if you prefer to writeSPEC_BEGIN
andSPEC_END
instead ofSpecBegin
andSpecEnd
.
Refer to this blog post on how to run specs from command line or in continuous integration servers.
- Please use only spaces and indent 2 spaces at a time.
- Please prefix instance variable names with a single underscore (
_
). - Please prefix custom classes and functions defined in the global scope with
SPT
.
- Dan Palmer (danpalmer)
- Justin Spahr-Summers (jspahrsummers)
- Josh Abernathy (joshaber)
- Meiwin Fu (meiwin)
- Shawn Morel (strangemonad)
Copyright (c) 2012 Peter Jihoon Kim. This software is licensed under the MIT License.