Trouble Adding OCUnit Testing Framework to Existing Xcode Project - ios

I am trying to integrate Unit Tests in my current Xcode project using the OCUnit Testing Framework. I have been following Apple's documentation:
http://developer.apple.com/library/mac/#documentation/developertools/Conceptual/UnitTesting/02-Setting_Up_Unit_Tests_in_a_Project/setting_up.html,
regarding setting up Logic Tests. When I switch to my testing scheme and run 'Test' under the 'Product' tab, I am receive two errors:
Error 1: Undefined symbols for architecture i386:
"_main", referenced from:
start in crt1.o
Error 2: ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I've tried cleaning my build and also using application tests but nothing seems to work. The tutorials I've views on Lynda seems not to run into these errors. Adding a target and linking it to my current project seems like all that needs to happen in order to start utilizing Unit Tests within Xcode. What do these errors mean and what do they refer to? All input is appreciated!

1) Create a new iOS project say one view controller type, and specify you want unit tests at creation, now you can see how Xcode has wired it - you will have a reference.
2) create a new project of the type and name as your current one in a temp folder. Move your original project file to another temp folder, move the new one to where original one was, then import all files checking unit test target.

Related

Swift UI Testing crashes when accessing enum rawValue

Xcode 7.3
Open Radar: rdar://25456632
In my app I have a string enum which I use to define some accessibility identifiers. For example
enum AccessibilityIds:String {
case ButtonFoo
}
I've built some UI tests where I want to search for controls. So I do something like this:
XCUIApplication().buttons[AccessibilityIds.ButtonFoo.rawValue]
XCode thinks this is fine and does not indicate any errors on the line. However when I compile the UI tests I get this compiler error:
Undefined symbols for architecture x86_64:
"myApp.AccessibilityIds.rawValue.getter : Swift.String", referenced from:
(extension in myAppUITests):__ObjC.XCTestCase.fooButton (myApp.AccessibilityIds) -> Swift.Bool in TestCaseExtensions.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Cross referencing the UI test target with the unit test target (Which compiles fine and uses the enum), I found that the UI tests did not have the Test Host set. Setting it meant that the UI test code would now compile, however the test itself then failed with a SIGKILL and the error:
testFooButton() encountered an error (Lost connection to test manager service. If you believe this error represents a bug, ...
So it appears that I cannot access enum rawValues in UI test code. Has anyone else come across this and managed to figure it out?
I'm still seeing this in Xcode 11.2.1
As a workaround I have placed fileprivate copies of the enums in the Tests.swift file.
This is working for me without any issues or warnings.
Click the source file go the Target Membership of the right panel, then tick the UITests target. Now it should work without any errors.

Linker error when accessing application module in UI tests in Xcode 7.1

I'm trying to implement some UI tests in my project. Everything goes fine as long as I keep it simple: record the test case, add some asserts, then run the test. This works fine, however when I try to access the application module from inside my test, the linker throws an error (See below):
In the application source file:
func foo() {
assert(true)
}
In the UI tests:
import XCTest
#testable import MyApp
func testExample() {
foo()
}
Error:
Undefined symbols for architecture i386: "MyApp.foo () -> ()",
referenced from:
MyAppUITests.MyAppUITests.testExample (MyAppUITests.MyAppUITests)() -> () in MyAppUITests.o ld:
symbol(s) not found for architecture i386 clang: error: linker command
failed with exit code 1 (use -v to see invocation)
Undefined symbols for architecture x86_64: "MyApp.foo () -> ()",
referenced from:
MyAppUITests.MyAppUITests.testExample (MyAppUITests.MyAppUITests)() -> () in MyAppUITests.o ld:
symbol(s) not found for architecture x86_64
I have found similar issue reported here:
https://forums.developer.apple.com/thread/20609
but no solution. Seems to me like the #testable simply doesn't work correctly. The guy on the developer.apple.com tried to workaround by adding the Test Host and Bundle Loader in the settings, but I don't think this is the correct approach. I think the #testable should just make everything work, and it doesn't look like it at the moment. Any help appreciated!
#testable import MainModule won't work for UI test, though it would enable code completion (may make you feel it works). It's designed only for unit test so far. And it would lead to build failure, something like:
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The workaround is to add the source code file to UI test target as well, then it will work out of the box (even without #testable import).
File Inspector -> Target Membership -> check UI test target (in addition to main target)
Hope Apple will fix it soon so that we can have a cleaner way to use it.
The UI tests are a separate module from the app, therefore not run inside your app as a logic test would. The only way for them to share code is to compile in all the app files you need to share between the two modules.
Check this blog for how you can achieve that, https://www.bignerdranch.com/blog/ui-testing-in-xcode-7-part-1-ui-testing-gotchas/
Also found a radar filed here, https://openradar.appspot.com/23116258
#testable import <yourApp> could actually be causing this bug. Just take out the line. It isn't needed for UI Tests.
"UI tests run outside your app in a separate process. You can’t access app code from inside a UI test - that’s intentionally part of the design. Use unit testing for tests that need to access the app code and UI tests to automate user interaction testing"
Notice at 6 minutes in, #testable isn't used by Apple Developers. https://www.youtube.com/watch?v=7zMGf-0OnoU&t=1316s

Equivalents of c# solutions and projects in xcode

Newly I am switched from xamarin.iOS to Xcode.
In C# a good feature is that you have a solution that contains several projects and you can define debug/build configurations and based on them build separate projects with each other.
Now, I want to know that is there any mechanism like this in the Xcode too?
Actually I want to develop 3 apps that they have many shared codes. So I want to create a base project that contains shared codes (and contents) and then 3 sub projects. Now with some thing like build configuration, I can build each of them that I want for publishing.
Does Xcode support mechanisms for this porpose?
UPDATE
By reading below answers I created a workspace with below structure:
I also added ../testproject/testproject to the build settings of link1Project but when I want to use files in testproject the autosuggest is not working and also when I build the link1Project I face with:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_ShowAlertView", referenced from:
objc-class-ref in mftTbnFlipsideViewController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Am I wrong in creating the workspace? Does the structure is right or I missed something?
You can have multiple targets for the same project, and each target can have different settings or files.
You can include this base project as a sub-project to each of those 3 projects (just drag it). And create a workspace to include all three child project in it, although it is not necessary - including project as a sub-project is enougth to share code between projects.

Trying to integrate unit tests into Xcode for iOS 5.0 project, but cannot get files to link correctly

I am trying to add unit tests into my Xcode project for an iOS app that I am working on. I have SenTest working with basic examples, but the second I try to test any of the project code, I get linker errors like so:
"_OBJC_CLASS_$_Account", referenced from:
objc-class-ref in Tests.o
ld: symbol(s) not found for architecture i386
Obviously, I could solve this by duplicating my app target configuration into my test configuration, making all of the compile sources the same and such, but this will make two different targets that I will have to maintain, which is very unappealing. Also, I could refactor the project to use a static library and share between the app and the test targets, but that also is undesirable.
Is there any way that I can use the built objects from the app target in the test target? This sure seems like a lot of work to get unit testing in my project...
Thanks for any and all help!

xcode 4 fails to initiate unit tests (with linker error) after I created a new scheme

My unit tests worked fine in xcode4 until I had to create a new schema to compile a package to run on my device for testing.
All I did was creating a new Target and a new Scheme, now I try to run the unit tests and get the following error:
The test bundle at [...]Tests.octest could not be loaded because a link error occurred. It is likely that dyld cannot locate a framework framework or library that the the test bundle was linked against, possibly because the framework or library had an incorrect install path at link time.
What did I break?
Like #Haoest and #Peter DeWeese above's comments to Answer 1 - I had exactly the same problem when I changed the product name.
To fix this for the case where you've renamed the product, you need to go to the Build Settings tab of the test target, and change the Linking section - the Debug and Release bundle loader settings. If you have renamed the product - the directory and name of the application may both be incorrect.
Thanks to both of them for pointing this out - but I thought this alternative fix for this situation deserved a higher profile than a comment.
I've also run across problems with Xcode 4 after adding a target to an existing project. I eventually figured out that the Xcode DerivedData for the project was damaged. By deleting that data, I caused Xcode to rebuild the data and the project returned to normal. I found the data in my home Library folder (~/Library/Developer/Xcode/DerivedData/).
I tried everything (including the other answers and those noted here http://twobitlabs.com/2011/06/adding-ocunit-to-an-existing-ios-project-with-xcode-4/), but finally found a different solution:
Set Deployment Postprocessing (in the Deployment section of Build Settings) to NO for the Debug target.
Before I did this, the executable was being stripped, and the link would fail with
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_SomeClassUnderTest", referenced from:
objc-class-ref in SomeTest.o
No matter that Strip Linked Product and Strip Debug Symbols During Copy were set to NO, it made no difference - only changing the Deployment Postprocessing setting finally made sure that the symbols were not stripped.
Same error message, in my case I wasn't linking one of the classes that were needed during the tests.
I discovered my problem was that I had 'Link time optimisation' enabled on my debug build. Setting it to no resolved the problem.
We were using nodejs-mobile which would build with the app but fail building with the tests.
Undefined symbols for architecture x86_64:
_start_node
In addition to all of the previous answers (build settings, search paths, making a brand new Unit Test, deleting DerivedData), what finally resolved it was creating a brand new new UI test instead of a Unit Test in Xcode.
It built successfully. Then you can copy your test definitions from your current test to the one one.
If you do not need the UI part, you can uncomment XCUIApplication().launch() in setUp of the generated tests, which makes it run as fast as before.

Resources