It seems like every time a new feature gets checked in, somebody fails to add it to the test target, and I get a linker error like this one:
Apple Mach-O Linker (ld) Error: _OBJC_CLASS_$_CLASSNAME referenced from…
The solution to this is not to just keep adding files to the test target. If you compile a source file both into your test target and your app target, you are compiling the same code twice. While on the surface this doesn’t sound so bad, in fact it can be:
Class MYCLASSNAME is implemented in both EpicPath1 EpicPath2. One of the two will be used. Which one is undefined.
This doesn’t sound so bad either, if you take a conservative view of “One of the two will be used”. After all, they’re both the same class. Apple, however, has quite a more whimsical outlook on things. Which class definition is used can change many times within a single compilation unit. So if you do something like this:
@implementation MYCLASSNAME static BOOL mysharedVariable = NO; + (void) setMySharedVariable:(BOOL) value {mySharedVariable = value; } + (void) test { [self setMySharedVariable:YES]; NSLog(@"%d",mySharedVariable); //prints 0 or 1 with ~50% probability }
It really gets surreal when you set the variable in one function, and you read it two functions deeper in the stack. Set your debugging context to the inner function, it returns 0. Set your debugging context to the outer function, it returns 1. Then you wonder if you will look back on the debugging session as the time when the voices started.
So what you should actually do is this:
Comments are closed.
Thanks very much! This resolved the aforementioned error that I ran into when adding my first test. The test ran fine when I didn’t reference any of my code but failed as soon as I did (so I think my bundle/framework path was entirely broken, as opposed to compiling twice).
Probably obvious, but I wanted to mention that you need to build the simulator version prior to running the unit tests.
Thanks again!
Owen
You may want to add the app target as a target dependency of the test target. This will enforce that the app target builds first.
Hi Drew,
thanks for the useful info. After I changed my setting per your blog , I’m getting new error as
ld: -bundle_loader can only be used with -bundle
1. I’m using XCode 4 and GHUnit.
2. From target project , I’ve created an object of class in main app.
3. From this object I’m trying to call the method in main app.
Can you please help me out with this ?
Also can you please share any sample unit test cases written which I can refer to will be of great help.
Thanks and Regards,
Vikram
I’m afraid I don’t know anything about GHUnit, I always use SenTesting which ships with XCode.