BDD style testing for iOS Apps

Posted: January 20, 2012 in iOS Development, Tools
Tags: , , ,

I would sound naive if I will try to emphasize on how important testing is for building a high quality application. Be it a consumer mobile or web app or large scale enterprise application. I have been playing with iOS ever since the first SDK was released. And hence, worked with so many customers, clients, enterprises (starting from startups to fortune 500 companies).

And I think about 80% of those customers or clients prefer to do their testing manually and track the test results in excel or Bugzilla which is always time-consuming and requires a significant amount of man-hours every time we want to do a proper testing. iOS apps now supports automated Unit testing by default. But Unit testing only ensures that an unit of your code works properly and doesn’t guarantee the application will run properly under all circumstances.

Cedar is a BDD-style testing tool for Objective-C similar to rspec in Ruby. The documentation available online is bit old and doesn’t really work with iOS5. Hence, I would jot down few quick steps on how to use this tool.

1. Download the framework from GitHub: https://github.com/pivotal/cedar

2. Build Cedar-iOS static framework. You might want to change the default “Derived Data” directory path from its default location to the your project directory. So that you won’t have to look up in the archive of your application folder to find the static library.

3. Add these flags under “Other Linker Flags” in your build settings. -ObjC, -all_load, -lstdc++

4. Add Cedar-iOS static framework to your project.

5. Comment out the default codes on main.m and add the below lines which will launch CedarAppDelegate in stead of your application AppDelegate. Another way you can do this is to select UnitTest while creating your project and modify the main.m under the test directory. So whenever you will test the application it will launch Cedar.

#import <UIKit/UIKit.h>
#import <Cedar-iOS/Cedar-iOS.h>

int main(int argc, char *argv[])
{
	@autoreleasepool {
		return UIApplicationMain(argc, argv, nil, @"CedarApplicationDelegate");
	}
}

6. Create a new (c++) file called AdditionSpec.mm and you can write your test specs on this file. You can use matchers, mocks and stubs. For these things you can refer to the GitHub project.

#import "SpecHelper.h"
using namespace Cedar::Matchers;

SPEC_BEGIN(AdditionSpec)

describe(@"BehaviorSpec"), ^{
	it(@"addition should work properly"), ^{
			1+2 should equal(3);
	});
});

SPEC_END

7. Build and Run. It will display all the test results in a table view.

Let me know if you face any issues in building or running it. Happy Testing. 😉

Advertisements
Comments
  1. danieldyba says:

    For step 5 to work the way you did it, you had to include the Cedar-iOS framework to your main project’s target, correct? I want to keep the frameworks in my targets separate, that is, I want my Specs target to only have the Cedar-iOS framework. I also kept the main file in my main project in tact and added a new main file under the Specs folder. I typed in the code as you did in step 5 in the main file under the Specs folder. How do you get Xcode to run just the Specs target? When I run the project, I don’t see the test results. Rather, I see the app launch.

  2. Subh says:

    @Daniel,

    Did you modify the main.m. UIApplicationMain object needs to be created with CedarApplicationDelegate in stead of default ApplicationDelegate. If you have done that correctly then probably your application is loading MainWindow.xib. Remove it from Info.plist

    – Subh

  3. danieldyba says:

    Thanks for replying Subh! I got it all set up. The problem was I was including the wrong folder for the Cedar-iOS framework. Now I’m trying to use an instance from a class in my app but I get a failed build. I imported the header of the model I wanted to test, but it looks like that’s not enough.

    Here’s my error:

    Undefined symbols for architecture i386:
    “_OBJC_CLASS_$_PriceCategory”, referenced from:
    objc-class-ref in PriceCategorySpec.o
    (maybe you meant: _OBJC_CLASS_$_PriceCategorySpec)

    In a ModelSpecs directory on the same level as the directory of my app, I have a file called PriceCategorySpec.mm. In this file, I import the correct header for PriceCategory.h, the model I want to test. This looks like a simple error. Got any ideas?

  4. danieldyba says:

    It turns out that I had to change configuration settings when building the app. See here: http://twobitlabs.com/2011/06/adding-ocunit-to-an-existing-ios-project-with-xcode-4/

  5. Subh says:

    Can u send me the full log trace?

    Use http://www.pastie.org/ to paste the log and share the link here. If you still face issues we might get into a Skype call over the weekend and I will help you out remotely in setting it up?

    – Subh

  6. danieldyba says:

    I got it to work thanks to the cedar-discuss Google group. It turns out the file I wanted to test didn’t have the correct target membership. I clicked on the file I wanted to test, then opened the File Inspector via CMD + OPT + 0 and ticked the Spec target. Thanks for your willingness to help!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s