Xcode unittest build failed with error "Undefined symbols for architecture x86_64"
IosXcodeIos Problem Overview
My unittest target build failed with below error:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_MCStore", referenced from:
objc-class-ref in MCStoreTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Basic information:
- Xcode6.2
- iOS8.2 SDK
What I have checked:
Symbols Hidden by Default
is NoOther Linker Flags
is -framework XCTestFramework Search Paths
is $(SDKROOT)/Developer/Library/Frameworks $(inherited)
Ios Solutions
Solution 1 - Ios
According to this link, I need to set Bundle Loader
with below content in unittest target Build Settings
$(BUILT_PRODUCTS_DIR)/MyExistingApp.app/MyExistingApp
Solution 2 - Ios
At least as of Xcode 7.3 test targets let you select a "Host Application". In the Test target (but not presently the UI Test target) this automatically populates the "Test Host" build setting, but not the "Bundle Loader", which can lead to classes not being found.
Considering this, if you set your test targets' "Bundle Loader" Build Setting to $(TEST_HOST)
, it will always contain the right value even if you change the Host Application.
This is effectively the opposite of the advice given in the link @yuwen-yan posted, and should amount to less work.
Solution 3 - Ios
This error may be the result of having wrong test target type, namely ui test target.
UI test targets can't use the internals of the main target, not even with @testable
imports. Unit test targets OTOH can use the internals.
See more details in this answer.
(I believe this has changed in some XCode version which causes confusion. Typical way is just to include a huge bunch of files from the original target in the ui test target. A proper way is to design UI tests in such a way that they don't need or use much code from the main target.)
Solution 4 - Ios
Experienced the same issue.
What fixed it for me was setting enable modules (c and objective-c)
to YES in the Testing target Build Settings
.
Solution 5 - Ios
In my case,I got this error when I need to test class that exist in framework that was part of my app :
testing framework class.
- Add testing target to macOS .
- Select project/targets window. Select the test target.
- Go to “build phases”, “link binary with libraries”, add the framework you want to test .
- In the test class (setup/teardown), add “import” to the class you want to test from that framework
Solution 6 - Ios
In my particular case I was trying to test release
configuration and was getting this particular error. After experimenting with different compilation flags I found out that setting Enable Testability
for release configuration on my projects (not particular targets but might work too) did the trick.
Solution 7 - Ios
Xcode 12.3 (12C33) – I just removed the testing targets and all references. Then created fresh new test targets, and, added back all my test files ✓ just works
Solution 8 - Ios
What worked for me was just using the test target on the podfile.
target 'MyAppName' do
use_frameworks!
pod 'SwiftLint'
pod 'RxSwift'
pod 'RxCocoa'
pod 'RxDataSources'
pod 'RxGRDB'
target 'UnitTestTarget' do
inherit! :search_paths
end
end
Solution 9 - Ios
Experienced the same linker error after adding test target to old project which was created 2 or 3 Xcode versions ago. Furthermore, project has various xcodeproject/target/bundle names. All possible renames, cleanings, Build settings
, Build phases
, Scheme
manipulations did not worked for me.
What did actually worked after a long struggle is recreating the project along with all targets from scratch in latest Xcode version. It finally links! And in this case you don't even need to manually modify Search paths
, Bundle loader
, Xcode will do it for you.
Solution 10 - Ios
For me I got a similar error message when I tried writing and running unit tests in a project that previously only had UI tests. After many hours of troubleshooting, I realized the problem was that my current testing target was only for UI tests, not unit tests.
To fix, I just needed to add a new Unit Testing Bundle target, and then make sure that each unit test file I was trying to run had its Target Membership set to the new target I just created.
Solution 11 - Ios
my two cents for people like me got this error using new(2019..) SPM. I got the same error importing a package in an (old) app.
As importing packages force Yo to choose target:
you doing have them in your test te, unless You: a) add Host application too test targrt b) flag "Allow testing Host Application APIs"
as here:
now remains the question how to test an app without running App too during testing....
Solution 12 - Ios
So here is what worked for me...
override func setUp() {
super.setUp()
let promise = expectation(description: "App has finished running")
DispatchQueue.global(qos: .background).async{
// Wait on the background thread
sleep(4)
DispatchQueue.main.async {
// Fullfill the promise in the main thread
promise.fulfill()
}
}
// Initialize the storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)
// Get the view controller
sut = storyboard.instantiateViewController(withIdentifier: String(describing: ViewController.self)) as? ViewController
_ = sut.view
waitForExpectations(timeout: 5) { (_) in
// Finish set up after the app is done running its code
}
}// End setUp() Method
Solution 13 - Ios
Below are the steps that I performed to fix the issue while trying to add unit test target in Xcode 9:
- Go to 'Manage Schemes'.
- Click on '+' button at the bottom.
- Select the newly added Target and select 'OK'.
- Make sure 'Shared' option is selected for the newly added target.