how to implement application tests in xcode4? - iphone

I'm trying to add some Tests for my application. Following the Document from Apple, I add two testing bundles to my project.
The logic tests are no problem, but when I try to make the application tests on a device I always get the error that the logic tests don't run on a device.
In Xcode 3 there is no problem with that. Only Xcode 4 throws this error...
Any suggestions?
Thanks, Tim

i was also having problems with setting up application tests in xcode4.
A solution that worked for me was as follows:
Assuming you have an application target called "MyApp"
Add a new target of type "other/Cocoa Unit Testing Bundle" to the project e.g "MyAppTesting". Here all Unit test files are located.
Go to MyAppTesting Build Phases and add MyApp as Target Dependency. This assures that MyApp is build before building the MyAppTesting target.
Open the Build Settings of MyAppTesting and change
Bundle Loader: $(BUILT_PRODUCTS_DIR)/MyApp.app/MyApp
Test host: $(BUNDLE_LOADER)
That causes the tests to run within MyApp.
Open the Build Settings of MyApp and change
Symbols Hidden by default: NO (for both)
Strip debug Symbols during Copy: Debug:NO
By doing so you do not have to include every .m-file into the test target.
To run the test on a device plugin the device and select the scheme "MyAppTesting on device" and run as test. Assure that the mentioned scheme has set "Debug" within Test/Build Configuration which should be default.
Best regards.

Related

Unit test - not showing TEST_TARGET_NAME in Build Settings

Maybe I have never seen this but shouldn't Unit tests show a TEST_TARGET_NAME
in build settings? I just added a Unit test target to an app that has Obj-C code mixed with Swift and I can't get the Unit test to run correctly. It crashes on run time. I have been looking at the build setting from unit tests to the UI test target that is already there and a few things come to mind. First, the non-existent test target name from build settings under User-Defined is not there and
Bundle Loader
has stuff inputted in it on the Unit test but not the UITest target and for some reason the 'Product Bundle Identifier' on the Unit test is different than on the UI test target. Also, 'Weak References in Manual Retain Release' is set to YES on UI but NO on Unit. Test Host is populated on Unit but not on UITest. Again the UI test target seems to run just fine but it doesn't reference any classes from the app. It literally just runs the UIApplication and does a run through the app. The Unit Test I get one main crash on run-time dealing with a
Thread 1: implicit Objective-C entrypoint +[<class name> UI] is deprecated and will be removed in Swift 4.
I will say I picked up this project and trying to clean a lot of it up but I feel like the previous developers just started upgrading to the latest and greatest versions of Xcode and never really migrating cleanly. Can anyone provide any input on this?

Xcode 8.1 No such module 'Foo' from unit tests [duplicate]

I recently updated to Xcode 7 beta 5. I tried adding a unit test to an earlier project, but I am getting the error message "No such module [myModuleName]" on the #testable import myModuleName line.
I tried
cleaning the project with Option Clean Build Folder
checking that "Enable Testability" (debug) was set to Yes in the Build Options
deleting the tests target and then re-adding the iOS Unit testing bundle
None of this worked for this project (but I have gotten testing to work in another project). Has anyone else had this problem and solved it?
Please check your Module Name that you try to import with #testable import "ModuleName". The module name should be the same on Target->Build Settings-> Product Module Name
The answer that worked for me
The answer was that I had some errors in my project that was making the build fail. (It was just your standard every day bug in the code.) After I fixed the errors and did another clean and build, it worked.
Note that these errors didn't show up at first. To get them to show up:
Comment out your entire Test file that is giving you the "No such module" error.
Try to run your project again.
If there are other errors, they should show up now. Fix them and then uncomment your Test file code. The "No such module" error was gone for me.
In case this doesn't solve the problem for other people, you can also try the following:
Clean the build folder
Open the Product menu, hold down Option, and click "Clean Build Folder..."
Make sure that Enable Testability is set to Yes
In the Project Navigator click your project name. Select Build Settings and scroll down to Build Options. Make sure that Enable Testability is Yes (for debug).
Delete and re-add your Tests target
If you have done the other things my guess is that you probably don't need to do this. But if you do, remember to save any Unit Tests that you have already written.
Click your project name in the Project Navigator. Then select your Tests target. Click the minus (-) button at the bottom to delete it.
Then click the plus (+) button and choose iOS Unit Testing Bundle to add it back again. As you can see, you can also add a UI Testing Bundle in the same way.
A few other ideas
Make sure that all required classes are members of your test target.
Make sure that you have added all the required libraries.
Make sure that the module name is written correctly (see this answer).
Or...
Leave a comment or answer below if you found something else that worked.
Related
How to do a Unit Test in Xcode
Xcode UI Test example
The problem for me was the iOS deployment target of the tests was not set to be the same as the main target. So be sure to check this.
In your test target:
Build Settings -> iOS Deployment Target -> iOS<same as the target you are testing>
So this is how I went about getting my code to work after trying all suggested solutions from prior suggestions.
I set 'Enable testability' to 'YES' in project's Build Settings
I also set 'Defines Module' to 'YES' in my project's Build Settings.
For the regular .swift file(s) within my project, say MyApp, I was going to write test cases for, I have both the main "MyApp" and the
"MyAppUnitTests" Targets checked under Target Membership.
I then selected my unit test file(s), declared the '#testable import
MyApp' at the top, beneath the 'import XCTest', and only checked the
"MyAppUnitTests" under Target membership
And everything worked like charm. Hope this helps.
One gotcha to watch for is that if your module name has a dash character in it - then you will have to refer to it with an underbar instead _. For some reason I suspected this might be an issue and it was indeed my issue.
eg. #testable import Ocean-Swift becomes #testable import Ocean_Swift
Just one other thing, if you do use the #testable syntax be sure to not include your production code in your test target. I've found this will cause inexplicable weirdness.
This sounds to be an error with the build settings of both targets.
You need to ensure that:
ENABLE_TESTABILITY equals Yes for both targets.
The PRODUCT_MODULE_NAME value of the test target should differ from the one of the application.
For those who have scrolled until the last answer and still nothing worked, here is what did it for me after following all other answers advices. I am using Xcode 11:
What caused the issue in my case was that I changed my Product Name
I changed my Product Name in the Build Settings of my main target to "New Name"
I had to re-select the Host Application for my test target
I didn't know that changing the product name would also change the Product Module Name, that is the one used for the module import in my test files. I changed my import as follows:
#testable import New_Name
It worked
I hope it helps
After spending couple of days on this issues finally I make it to work with my project. Problem was in Bridging Header - path in Tests target can't be empty if you are using Bridging Header in your main target
Hope it will save some time for someone.
One other thing to check: If you have an Objective-C project, but are writing unit tests in Swift, make sure the main target uses at least one Swift file!
More info:
I was working on an Objective-C project, but wanted to write unit tests in Swift.
I added a Swift file to the main target to generate the necessary ProjectName-Bridging-Header.h file, wrote my tests and everything was working properly.
Later on I deleted the Swift file because I thought I didn't need it (all of the main target's code is in Objective-C... I was only writing tests in Swift).
I didn't notice a problem until later, after I did a "clean/clean build folder" and the "No Such Module" problem showed up. After some head scratching I added a new blank Swift file and the problem went away.
I've tested it multiple times with/without the Swift file, and it only works with it... so, I'll either need to leave the blank file in the project, convert some Objective-C into Swift, or add some new code to the project written in Swift.
In my case , I had 3 issues.
The first was that I had to specify the import path in :
Target -> Build Settings -> Swift Compiler - Search Paths -> Import Paths
The second was that I was using Pods and I had to import these pods to my tests as well using :
target 'MyAppTests' do
inherit! :complete
end
The third one as that I was using a bridging header in my target , thus I had to specify the bridging header to be the same for the test.
Make sure under the test scheme's build setting, the test target is in the list.
Beside the play button, select the test scheme, then Edit scheme..., go to the Build section, click plus + and select the target you want to test against.
In my case, we have an internal target that we develop with (a few minor differences) and after a merge, it was removed from the test config.
Here is yet another thing to check that is not listed. For me, it had something to do with my team, perhaps because our Team's Agent had not yet agreed to the latest License Agreement! Once I selected a different Team in my Target's General settings, AND then I specified a specific Deployment Target like 12.1 or 11.0, suddenly the "No Such Module" warning went away.
If you have some targets in your project -
check your TARGETS in Module Name that you try to import with #testable import "TARGETSModuleName".
The module name should be the same on:
Target -> Build Settings -> Product Module Name
For example:
I followed the steps above, which worked. However, my project had some more issues. I got this warning and I could not access classes from my main project to test in my test target.
I found that your Test target Product Module Name (YourTestTarget -> Build Settings -> search for product module) cannot be the same name as your project name.
Once I changed the Product Module Name for my test target everything worked.
I tried all the answers here but the red flag would not go away. But I got it to work by just "running" an empty test regardless and it cleared up.
Things I would like make sure are done:
Host Application
#testable import "Module_name" (make sure the module name is correct)
Make sure you deployment target for the test is the same as the project
XCTest does not need to have Target membership
XCode 12.6 beta
I'm not sure what caused this issue for me but cleaning my build folder didn't sort it. Restarting XCode didn't sort out the issue either.
What worked for me was deleting this line: import XCTest, and then retyping it again.
My issue was that the class i wanted to test was supposed to be in a separate module (API Client), but the class was actually a member of the app target and not the framework target. Changing the target membership of the class made the import error go away!
Environment: Xcode Version 9.0 (9A235)
Scenario: Testing an open-source framework.
I had the same problem: 'No such module'.
Solution:
Select the Test target.
Select Build Phases
Add the framework to be
tested via Link Binary...
Here's the test file:
I had this same issue. Cleaning the build folder and restarting Xcode did not work.
What did work for me was ensuring that the setting for "Build Active Architecture Only" of your test target and scheme matches the setting of your app's target and scheme.
XCode 12 Development Beta 3
The error fixed itself after I've built the project for the first time.
This is what worked for me with Xcode 13.1:
In the Locations tab in Xcode Preferences > Locations I had defined a Custom location:
This caused not only unit tests to fail with the dreaded "No such module" error, but also also "Command CodeSign failed with a nonzero exit code" and other warnings and errors.
Changing the setting to Unique:
fixed all problems.
It could also be:
Not set the hosting application for your test target (in the general tab or TEST_HOST build setting)
Missing the app dependency in your Build Phase for your test target.
For me the solution was to rename
#testable import myproject_ios
to
#testable import myproject
after I had updated product name of target myproject-ios in Build Settings/Packaging/Product Name/ from ${TARGET_NAME} to myproject.
This was fixed for me when I changed the Deployment Target from 9.3 to 11.0.
General > Deployment Target > "11.0"
If you are using xcodebuild and find this problem, consider adding in a workspace flag to the build command.
Changed This
$ xcodebuild -scheme PowToonsTests -destination 'name=iPhone X' test
To This
$ xcodebuild -workspace PowToons.xcworkspace -scheme PowToonsTests -destination 'name=iPhone X' test
In build settings test target, check the host testing, it takes the name set in PRODUCT_NAME.
It is that name that you should use in test classes.
I recommand to not change PRODUCT_NAME (match name of the main target)
I think this may have happened because I deleted the example tests.
I removed the Unit test bundle then re-added it as shown in the pictures below and all was well again.
CocoaPods recommends adding inherit! :search_paths to your test target like so:
target 'App' do
target 'AppTests' do
inherit! :search_paths
end
end
Source: https://github.com/CocoaPods/CocoaPods/pull/8423#issue-244992565
Tried all the solutions. Nothing worked. The Xcode build cli failed on a swift package module not found error.
error: no such module 'Apollo'
import Apollo
Removing the Test targets and re-adding them worked for me.
I changed the name of my project as I didn't want my original name for the app to show in the app store. This necessitated a change in my app host, which necessitated a change in the import I made.
Old name: QRCodeTarot
New name: Pointy Hat Tarot
This is the change I made for my host in my version control client.
This meant that in my tests, I needed to change the name of the import to the display name of my app. So even though my project was named QRCodeTarot, I needed to change the import to the display name.
So I went from import QRCodeReader to import Pointy_Hat_Tarot.
The recommendation to make your project name match your test import name is wrong.
The import name should match your project's display name, not your project name

Cannot load underlying module for XCTest

I'm working in swift on Xcode and by default it creates a test file that references XCTest.
When I set the target membership to my main project it causes this error
Cannot load underlying module for XCTest
If this target membership is not set the tests runs properly and everything works fine.
Double check that the file in question is not in the main target but instead only the test target. Only the test target will have that framework to import.
The main project does not link with the XCUnit framework. You should create a separate testing target for your project, if one does not already exist, and add your test source files to that target.
Select your project in the Project Navigator. This will open the project's settings in the editor.
Click the "+" button at the bottom of the column listing your Targets.
If you are working on an iOS project template, select iOS > Test > iOS Unit Testing Bundle.
If you are working on an OS X project template, select OS X > Test > OS X Unit Testing Bundle.
You've just added your tests file/class into main target and not into test target by mistake. Simple as that.
Solution:
1) Remove test file from "Compile Sources" list on "Build Phases" tab for main target
2) Add same file into "Compile Sources" on "Build Phases" tab for test target
It must resolve the issue
I get this error if I create a macOS dynamic framework target, which links to XCTest.framework (the target is a framework target, not a testing target!).
In this case the problem is solved by adding
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks
to project's "Build Settings / Framework Search Paths".
After lots of troubleshooting and bouncing around Stack Overflow pages such as this one, I managed to find one detail that was not mentioned on the other iOS Unit Test troubleshooting pages.
If your project uses CocoaPods, make sure to include your test target nested inside your main application's target. Your podfile might not include it if you created your test target after running pod init. Your podfile should look something like this:
target 'YourApp' do
target 'YourAppTests' do
inherit! :search_paths
# Pods for testing
end
end
Remember to save your podfile and run pod install after doing so.
Hope it helps!
This maybe a little late but what you have to do is:
Click on File > New > Target > iOS Unit Testing Bundle.
And then add your tests in there. This worked for me. The problem was that I didn't select create unit tests when I created my project.
Hope this helps someone.
While the accepted answer solves this problem for majority of times, there is one more way you can come across this error.
If you have already ensured that:
As pointed out by #pwc #nick-n and others
The ClassTest.swift file for target membership by ensuring that it is only attached to the Testing target.
The ClassTest.swift is not visible under you main app target > Build Sources > Compile Sources
Here is what else you can check:
in your .podspecs file
Ensure that your source_files does not directly or indirectly includes the testing directory.
for example :
s.source_files = ["Classes/**/*.{swift}", "Classes/**/*.{xib}"]
s.exclude_files = ["Classes/Exclude", "Classes/MyPodProjTests/"]
Note that Classes/**/*.{swift} includes everything overriding the fact that the directory MyPodProjTests must be excluded.
Solution:
s.source_files = ["Classes/MyPodProj/**/*.{swift}", "Classes/**/*.{xib}"]
Note:
This is extremely edge case and completely human error but I thought it will be worth point out.
This problem occur two times in your project.
When you Don't Add UnitTestingBundle in your project when create a New Project.
When you install CocoaPods in Your Project sometime not every time.
1:Answer:
Go to the File Click on File.
Then You see First option New Click on it.
After Clicking on it you see Some Option Click on Target.
And then in the Searchbar Search IOS Unit Testing Bundle and Add Problem is solved.
if Compiler can't give you a permission to add this then try Second Method when is given Below.
2. Answer CocoaPod Problem:
Go to the Product Click on the Product.
Click on clean or press cmd+k.
Problem is solved.
Make sure the Target Membership is checked off for all the modules when the test framework is selected. You can view the Target Membership option by selecting View->Utilities->Show File Inspector
In my case, I was making the tests for a private pod, so in the podspec was like:
s.test_spec 'Tests' do |test_spec|
test_spec.source_files = 'Tests/*.swift' end
But in the Podfile I forgot to bring the test specification, as such:
target 'MyApp' do
use_frameworks!
pod 'CoconutLib', '~> 1.0', :testspecs => ['Tests'] end
I did all the above, but still I was not allowed to access the methods I wanted to test. But before I wrote any test case built the project once and then the methods were accessible to test. So do try it and let me know if it solved any ones problem.
I had the same problem and the solution for me was to:
Select my scheme
Edit Scheme...
Then when Scheme configuration window is opened select left tab named "Test" to be redirected here:
Like you can see my UITests are not added here but exist in my project so I had just to tap plus button and select my UITests target like this:
Then tap "Add" button and close configuration view
Finish with a clean of project and try again it should work
And don't forget to verify that too: https://developer.apple.com/library/archive/qa/qa1954/_index.html
Hope this answer will help.
PS: one last think in my Test target in build settings I had to check these property that was not configured correctly:
DEBUG_INFORMATION_FORMAT = dwarf;
ONLY_ACTIVE_ARCH = YES;
VALIDATE_PRODUCT = NO;
Just as #Alfishe mentioned above:
You have to remove the test files from Compiler Sources under Build Phases
As shown below
Check Target Membership of your Test class.
The problem is that Unit Testing Bundle as a target should be created beforehand
[How to add it]

adding SenTest test target after creating the project

Anyone know how to get Xcode to recognize you've added a testing target so you can run the tests, cmd+U? I added the target but I'm missing something to tell Xcode or the project that there is a test suite to run (Test is grayed out in the Product menu).
you learn something new everyday:
just messing around in xcode found "Edit Scheme" when you click on the target to run, you'll see it in the list below your current target (to the right of the Stop button).
Then go to Tests and then click the add button and add your test target:
Also note the test targets you create from the New Target menu are logic tests but the ones create by the New Project menu are application tests. Logic test are stand alone but in application tests your test code is injected into your application.
To make a logic test into an application test set the BUNDLE_LOADER and TEST_HOST in your test target build settings
BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/DC Wire Sizer.app/DC Wire Sizer";
TEST_HOST = "$(BUNDLE_LOADER)";

Unit Testing iPhone - Linker Errors

I've followed the Unit Testing Applications guide from the iPhone Development documentation. I followed all the steps and it worked with the TestCase from the documentation. But as soon as I changed the TestCase to test real Code from my project I ended up with linker errors. All classes that are used in the TestCase are reported as missing.
I've already searched the internet and found that the Bundle Loader property must be set to "$(BUILT_PRODUCTS_DIR)/MyApplication.app/Contents/MacOS/MyApplication". But this also fails because the file could not be found.
Any ideas what I have to do to tell the linker where to search for the missing files?
Make sure that you have added your classes to the unit test target. So if you are creating a unit test for class foo right click on foo.m, select info and then from the Targets tab ensure the checkbox for your unit test target is selected.