Migration of OCUnit to XCTest leads to linker error - ios

I've tried to migrate our OCUnit to XCTest. So I have 100% compilable project but I see next linker error:
Error:Undefined symbol '_OBJC_CLASS_$_XCTestCase' referenced from:...
My "Framework Search Paths" looks like this:
$(SDKROOT)/Developer/Library/Frameworks (non-recursive)
$(inherited) (non-recursive)
$(DEVELOPER_FRAMEWORKS_DIR) (non-recursive)
I'm not familiar what else to do to satisfy linker

I am seeing the exact same error messages in Xcode 6.1 after migrating with
Pull Down Menu → Edit → Refactor → Convert to XCTest.
I got 2 solutions:
Solution 1 (recreate test project)
Backup all source files in your test project.
In Project Navigator, select the project.
This shows the project settings.
In the project settings, click Show project and targets list.
Select the test target, and press delete to delete it.
In Project Navigator, select the test target, and press delete to delete it.
In Test Navigator, click the + button on the bottom left, and choose New Test Target.
Add your original source files back into the new test target.
Now test your project as usual.
Solution 2 (hackishly modify test project)
In Project Navigator, select the project.
This shows the project settings.
In the project settings, select the test target (not the main target), then select Build Phases.
In Link Binary With Libraries, click the + button.
This shows the list of frameworks, but there is no XCTest.
Choose a framework that you don't use at all, say, Twitter.framework, and click Add.
Open your project file (something.pbxproj) in a text editor, and replace all occurrences of Twitter.framework with XCTest.framework.
Note: the pbxproj file is inside the .xcodeproj folder. In Finder, you have to right click on the .xcodeproj and select Show Package Contents.
Go back to Link Binary With Libraries in Xcode, and check that XCTest.framework is added.
If not, try restarting Xcode.
If it is added but is red, just ignore it. Xcode can't find the framework, but the linker can.
Now test your project as usual.

Related

How to add the parent path to RealmSwift.framework in the “Framework Search Paths” section?

This is step is listed in the instructions for installing Realm. link here: https://realm.io/docs/swift/latest/
I am new to xcode and I don't understand how to complete this step. Can someone give me detailed instructions? I found the Framework Search Paths section in the build settings, but I don't even know what it means to add a parent path.
I also need help with the next step, creating a new run script phase.
xcode ver 6.4
If you follow to 2nd step correctly, the project directory will be like following:
Now, you can build main app's target fine. However, if you execute the unit test with Realm, it will be failed to build due to it cannot find the framework. So you should tell where in the framework is. (More precisely, you should also set the Framework Search Paths for the app's primary target. It was set by Xcode automatically when step 2 is done.)
To set the Framework Search Paths for the unit test target, do the following steps:
Click the project in the "Project Navigator" of Xcode
Click the unit test target in the "TARGETS" section
Click the "Build Settings" tab
Scroll down and find the "Search Paths" section
Double click the value of "Framework Search Paths"
Click "+" button in the bottom-left of popover
Add $(PROJECT_DIR) to text field
("Parent path" is the place where is in the framework. The framework in the project root directory that is represented $(PROJECT_DIR).)
Press "enter" key to accept the text
Please see the below image:
Now, you have done to the step 3. Step 4 is following:
Click the main app's target in the "TARGETS" section
Click "Build Phases" tab
Click the "+" button in the top-left corner
Select the "New Run Script Phase"
Open "Run Script" section that added
Paste the following snippet to the text field
bash "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework/strip-frameworks.sh"
The step 4 is not required for development, but it needs to work around an App Store submission bug when you submit the app.

How to delete an Xcode Swift Test Class from the Test navigator?

The Xcode Test navigator shows a list of test case classes.
I want to delete a test case class because it's no longer needed.
I've tried many typical approaches, such as pressing delete, or looking for a "-" icon, or "Remove" menu item, or searching for help in Apple Xcode documentation.
I've found this workaround:
In the Project navigator, remove the file from the project and delete the file.
Quit Xcode and re-launch it. The Test navigator seems to lose track of the test classes and test cases, and show zero items.
Run the tests. The Test navigator seems to rebuild the list of test classes and test cases.
If that still doesn't work, try these...
Delete Xcode Derived Data:
Xcode menu -> Preferences -> "Locations" icon -> "Derived Data" section.
Click the tiny gray circle arrow; this opens the Finder and shows the DerviedData folder.
Delete the entire folder.
Rebuild:
Product menu -> Clean.
Product menu -> Build.
Is there a simpler way to accomplish the goal of deleting a test class? Ideally without needing to relaunch Xcode, or rebuild the project, etc.?
Related kind of issue: How can I delete Xcode test cases from the test case view?
I'm using Xcode 6.3 and Swift 1.2, if that helps to know.
Edit: In the comments, #CouchDeveloper points to the official Xcode 6.3 release notes, which describe a known bug # 20373533:
Swift tests are not automatically discovered in this release of Xcode. Test annotations in the source editor sidebar will not appear, and the test navigator and the table of tests in the Test action of the scheme sheet will be empty. ...
The bounty on this question is for any solution or better workaround. Any workaround is fine, such as using the Xcode GUI, or using command-line xcodebuild, or any shell script that kludges the project files.
If you want to delete just a single test class, you can click on the file name in the Project Navigator and press Delete and Move to Trash.
If you want to delete then entire Testing bundle, click your project name in the Project Navigator. Then select your Tests target. Click the minus (-) button at the bottom to delete it.
It is a good idea to do Unit Testing (and UI testing) in your projects. So if you want to add them back in then just click the plus (+) button.
See also
How to do a Unit Test in Xcode
Xcode UI Test example
Using Xcode 6.2, all I had to do was to switch to the Project navigator, select the file, and press delete. I then clicked the "Remove Reference" button in the confirmation dialog that appears. After that, the tests in that file disappeared from the Test navigator immediately. Adding the file back, the tests reappeared.
I didn't have any need to delete the derived data folder, restart Xcode, etc.
Adding the file to the project again instantly restored the tests in the Test navigator.
This is certainly the desired behavior, and it sounds like it's broken in Xcode 6.3 but possibly fixed again in 6.3.1. So the real answer may just be that you need to upgrade to 6.3.1 (or downgrade to 6.2).
Before:
After:
You can add and remove tests to the project easily using the class target membership checkbox. Find the class file in the Project Navigator and select it, then in the Utilities pane, click on the File Inspector and you will see a checkbox for target membership. You can toggle it on and off in there.

Xcode won't add "Embedded binary" after deleting "DerivedData"

Alternative titles to aid search:
Adding Embedded Binaries fails in Xcode
Xcode won't link framework from separate project
App crashes on device because of missing framework, works in simulator
Overview
After deleting the "DerivedData" folder (or performing a "Product > Clean") in xcode6, I cannot add CocoaTouch frameworks from another project to the "Embedded Binary" section (under General tab).
Or, Xcode hits a linker error because it cannot find a framework that if previously could.
Other symptoms
Clicking on the + under "Embedded Binaries" shows the Framework selector but selecting a framework in different project in the workspace does nothing.
When you add the framework to the Embedded Binaries, there will be a reference added to your project for it. If you select that reference after your steps above, you will probably find that it has an Absolute Path reference to the framework rather than a relative one, which we'd like. Change the location to Relative to Build Products and the reference should always be discoverable if do a "hard" clean or use another computer etc.
I have made a video which describes how best to add a built framework from one project to an app target in another sibling project.
This it the only way i have discovered to restore the embedded binaries, please leave comments if you find some steps are not required.
Prerequisites: Read Daniel Tull's answer.
Remove all framework projects from the workspace
Perform a "clean build" and/or remove the "DerivedData"
Add project back into the workspace
Build the project (possibly optional)
In the General tab of the app target click the + under "Linked Frameworks and Libraries", select the framework.
Build and run in the Simulator (there should be no issues building or running)
Build and run for device (this might cause a crash due to the framework not being correctly linked, ignore this crash)
Click the + under "Embedded Binaries", select the framework. This should add it to the project (possible duplicate under "Linked Frameworks and Libraries")
Repeat for all required frameworks
Once building and running (on device) is confirmed you can remove any duplicate (and/or red) frameworks in the Project Navigator or target General tab
Just to add to #Daniel's answer, if your Location dropdown is greyed out you may have selected the wrong file. Make sure to select the framework that's in your app project (not framework project).

Import XCTest in to existing project

I added a new target as a Cocoa Touch Unit Testing Bundle, named the directory "MyAppTests", and the actual framework is not active-- it is highlighted red
When I add the framework by the 'link binary with libraries' in the 'build phases' tab technique, a new Framework is added, instead of updating the one that was created with adding the target.
When I go to run the code, I then run in to all sorts of troubles, ranging from linking errors to other frameworks not being recognized.
How can I activate the XCTest.framework that was generated when I added target? Please help, thank you!
XCTest.framework is the bundle that Xcode uses to enable
#import <XCTest/XCTest.h>
To add test cases to an existing project select the target, right click > file > new > objective c test case class. Then in your build phases you can add the XCTest.Framework. Make sure you check the add to target boxes when creating the test case.

XCode: Can I delete test target?

What would happen if I delete the test target for my app? Would this affect my other target? How would I go about properly deleting the target?
Select '.xcodeproj' file from project navigator, then select 'Show project and targets list' icon, select 'target' to delete and then click '-' at bottom
If by test target, you mean a unit test target, then deleting the test target would mean you couldn't unit test the code in your project. Deleting the test target wouldn't affect the other targets in your project.
To delete a target select your project from the project navigator to open the project editor. Select the target you want to delete from the left side of the project editor and press the Delete key.

Resources