Starting with an app already in development, I have carried out the instructions in the iPhone Development Guide – Unit Testing Applications
I can successfully include and use my App's classes in Application-style tests that run on the device, and output their results to the console.
If I add the following line of code:
STAssertTrue([viewController isKindOfClass:[LoginViewController class]], @"Top view controller is not LoginViewController");
The following build error is generated:
Undefined symbols:
"_OBJC_CLASS_$_LoginViewController", referenced from:
__objc_classrefs__DATA@0 in LoginViewTest.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
I can provide more configuration information for the project and the Testing target, but the setup works file without the [LoginViewController class]
line in the test source.
Without that line, I can reference the class, use it's properties and send it messages successfully.
Is there a linking build setting, or bundle loading option that is required when attempting to use an App class in this fashion? Or should I find another type of test to confirm that the class of an object is the expected one?
I have found an answer, but I think there must be a "better" way?
In the build configuration for the Unit Tests bundle, you can specify the Bundle Loader (BUNDLE_LOADER
) setting that points to your "host" App.
${TARGET_BUILD_DIR}/AppName.app/AppName
The Unit Tests bundle is being built as a dependency of your App's unit testing target (say, AppName Testing
), and as a result I haven't been able to resolve the App executable any better than the above.
The net result is a working unit test injected into the Testing target without any linker errors. The tests run and access the classes as expected.
EDIT: Bundle Loader – Target Configuration
It's important to configure the target that is "hosting" the testing bundle to not hide it's symbols.
GCC_SYMBOLS_PRIVATE_EXTERN = NO
a.k.a. "Symbols hidden by default". From the documentation:
When enabled, all symbols are declared
'private extern'
unless explicitly marked to be exported using'__attribute__((visibility("default")))'
in code. If not enabled, all symbols are exported unless explicitly marked as'private extern'
.For more information, see http://developer.apple.com/documentation/DeveloperTools/Conceptual/CppRuntimeEnv/Articles/SymbolVisibility.html.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With