how do I setup cedar for bdd testing of ios apps?

1.1k Views Asked by At

I'm trying to set up cedar and having difficulty getting it to work. I'm trying to follow the instructions on github.

I'm using xcode 4.2.

The first step I'm not sure about is this:

"Create a Cocoa Touch "Application" target for your tests in your project. Name this target UISpecs, or something similar."

a) I'm not sure if I'm able to use ARC for my main application when testing with cedar. b) I'm pretty sure I'm not able to use ARC for building cedar itself, and I don't think I'd want to. c) I'm not sure I'm able to use ARC for the tests project that will house my specs. d) I'm not sure which application template I should use to create the application to house the specs.

I created a new main application using ARC and the single window application template. I created a new application to house my specs without ARC, using the empty application template.

When I open the plist.info file for the test application that houses my specs, I don't see an option for "Main nib file base name". So I am ignoring this step.

Now I come to the step:

"Add the Cedar-iOS static framework to your project, and link your UISpecs target with it."

So I went to the specs application build target and added the ~/Library/Developer/Xcode/DerivedData/Cedar-borwneaogydgaodbtmfyaccykqxn/Build/Products/Debug-iphoneos/libCedar-StaticLib.a file to the project under the "link binaries with libraries" tab under the "build phases" tab.

Then I added -ObjC, -lstdc++ and -all_load to the Other Linker Flags build setting for the UISpecs target.

Next, under the application that houses the specs, I created a new file called TestSpec.m and added this code to it, in an attempt to get a failing spec:

#import <Cedar/SpecHelper.h>

SPEC_BEGIN(FooSpec)
describe(@"Foo", ^{
    it(@"should do something", ^{
        expect(0).to(equal(1));
    });
});
SPEC_END

When I tried to run the specs project in the simulator, I got some errors about alloc and autorelease not being supported when using ARC. I suppose this means my main application cannot use ARC while my spec application does not. I deleted my spec application and tried again, this time using ARC.

I removed the autorelease pool and release code from the main.m code to comply with ARC.

I now get two build errors:

1) in main.m: file://localhost/Users/nelsond/workspace/BIM360UIArchitecture/BIM360UIPrototype/BIM360Issues-IOS/BIM360Issues-IOS-Specs-ARC/main.m: error: Lexical or Preprocessor Issue: 'Cedar-iOS/Cedar-iOS.h' file not found 2) in TestSpec.m: file://localhost/Users/nelsond/workspace/BIM360UIArchitecture/BIM360UIPrototype/BIM360Issues-IOS/BIM360Issues-IOS-Specs-ARC/TestSpec.m: error: Lexical or Preprocessor Issue: 'Cedar/SpecHelper.h' file not found

I'm pretty stumped on what to debug next.

2

There are 2 best solutions below

0
On

Here is some points that I encountered when integrating Cedar in my iOS application.

  1. "Cedar-iOS static framework" seems to refer the following folder: ~/Library/Developer/Xcode/DerivedData/Cedar-borwneaogydgaodbtmfyaccykqxn/Build/Products/Debug-iphoneuniversal/Cedar-iOS.framework . Not the one with .a extension.

  2. I was able to enable ARC without any issues since the static framework already compiled without ARC.

  3. I also did not see any "Main nib file base name" key in my info.plist
  4. The first piece of code is my main.m for test target (I needed to modify it, by looking at my main application's main.m)
  5. The second piece of code is the spec code that resides in a file named "MyAppDelegateSpec.mm"

#import <UIKit/UIKit.h>

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

#import "MyAppDelegate.h"
#import <Cedar-iOS/SpecHelper.h>

using namespace Cedar::Matchers;

SPEC_BEGIN(MyAppDelegateSpec)

describe(@"MyAppDelegate", ^ {
   __block MyAppDelegate *appDelegate;
    beforeEach(^{
        appDelegate = [[MyAppDelegate alloc] init];
        [appDelegate application:nil didFinishLaunchingWithOptions:nil];
    });

    afterEach(^{
        appDelegate = nil;
    });

    it(@"initializes window", ^{
        expect(appDelegate.window != nil).to(be_truthy());
    });
});
SPEC_END
0
On

a) you can use ARC for your main app target.

b) not sure why you're asking this, Cedar itself isn't supposed to be built with ARC. Anyway, just use the default configuration, no need to mess with that.

c) you shouldn't use ARC for your test classes.

d) if you create a new project, you can use the default auto-generated OCUnit target.


I've been using Cedar with my iOS apps for a few months now, and I really like it.

I use it with OCUnit, so I can just hit Cmd+U to run my tests, and I have a specific scheme to run them from my CI server.

I prefer to create a git submodule to get Cedar's code, without ever editing its files. You can simply drag Cedar's Xcode project into your app's workspace. It's best to use the static library. Add the linker flags, like you described. You'll also need to tell Xcode where to find the header files (User Header Search Paths, with something like "$(PROJECT_DIR)/Libraries/cedar/Source/Headers"). Now you should be ready to go.

I disable ARC (see How can I disable ARC for a single file in a project?) for my test classes. Note that ARC configuration is really file-specific, so you can include files from your main target (with ARC) into your test files, they'll mix just fine. A bit confusing sometimes, but quite powerful.

Hope this can help.