Can't access app code from XCTest - ios

I have a growing swift project that I have been writing both unit and UI tests for along the way. My UI tests run just fine, but my unit tests have stopped compiling. I am using "#testable import X", but anytime I try to access a class from the project, even if I make that class public, I get a "Use of unresolved identifier" error. I have no idea what I could have changed to cause things to start failing.

Choose "Clean" from the Xcode "Product" menu and then recompile. That will often get it working again. For some reason, we have to "Clean" before the classes are made available to the test target.
My original answer below outlines the old solution before #testable was available to us.
--
Make sure the source file for PostCell is included in the list of source files for the tests target.
You can do this by going to the tests target and adding it to the list of "Compile Sources":
Or by clicking on "Target Membership" to the "File Inspector" for the source in question:

Related

Errors when add class UITest target

I have a simple weather app which gets data from OpenWeather API. I wanted to add UI tests to project. I added some classes to AppNameTests target in Target Memberships and after that I got many error in that class. But test is working and project build correctly and run without any problem. Is somebody know how to resolve this problem?
EDIT:
Your app's source code files should not be members of the unit test and UI test targets. To access your app's classes, structs, and functions in your tests, use the #testable import statement in your test classes.
#testable import AppName
Regarding Xcode showing a bunch of error messages when the project builds and the tests run without error, you can clean your build folder by choosing Product > Clean Build Folder, and see if that makes the error messages go away.

Cannot load underlying module for unit tests

I am currently developing a swift framework for my iOS class.
Here is the project structure :
I would like to test my class named SimpleCoreData, but when I go to the generated ESGISimpleCoreDataTests file, the import (also generated) isn't accepted:
Cannot load underlying module for 'ESGISimpleCoreData'
So I checked this other topic, and verified the targets, but everything seems fine.
framework:
tests build phases:
I am beginning in Swift, so I may have missed something obvious. Can you please help me with this one?
Finally, after examining each commit to see where it breaked, it turns out that the problem was probably coming from a unit test file I created, which had the same issue (probably didn't created it correctly), and then only removed its references instead of moving it to trash.
So I went a commit backward, used the default unit test file generated, and it worked.
Here's another variation on this theme. 🎢🎡
I imported a folder of files into my main project, and in that folder was a file which had import XCTest in it.
The compiler didn't flag this problem, and I didn't see it until I used finder (like CodingMouse).
Once I moved this testing file to the UITests folder and changed its "Target Membership" to the UITests Module, I did a clean and build to get everything working again.
So the takeaway from this is the compiler won't always point you directly to the actual problem. Using finder, scan through your files and confirm nothing looks suspicious or out of place. πŸ€

How to unit test an app extension on Xcode 6

Does anyone know how to perform unit testing on app extension target, especially keyboard extension target?
What have I tried (in the unit test target):
In the "General" tap, set it's target to the extension target instead of the container app.
Set the "Bundle Loader" to the path of the binary of the extension target, which looks like $(BUILT_PRODUCTS_DIR)/com.mycompany.keyboard.appex/com.mycompany.keyboard
Set the "Test Host" to $(BUNDLE_LOADER).
In the "Build Phases" tap, set the "Target Dependencies" to both the container app and the extension.
After these things done, I can build it successfully but always get "Test Failed" with an log Test target SogouInputTests encountered an error (Test session exited(1). without checking in. If you believe this error represents a bug, please attach the log file at /tmp/TestStatus-UXfvxw.log).
I'm using Xcode 6 beta 3.
I have reported the bug to Apple. And sadly, the answer is that the keyboard extension is not support unit test now. The answer comes from Apple:
It's not currently supported to run unit tests inside an app extension
Instead, factor the code you want to test into a framework and test the code there
Link the framework into your extension
Just ran into similar issues trying to unit test an extension. Independently did exactly the same thing the author tried with Bundle Loader pointing to .appx path with no success of course.
I really did not like the idea of creating a separate framework just for testing so I ended up of adding testable source into the extension test target. It is really simple if you don't have too many source files in your extension:
Select you extension test target in Project settings
Go to Build Phases
Expand Compile Sources
Click +
Add source files with your testable code.
Build for Testing
Why it works:
Once you add extension sources into your extension test target, XCode is going to double reference each of them and compile in both the normal extension build and the test build thus eliminating linking issues.
Are there any drawbacks?
You will have to manually synchronize the source file list in the extension test target. Whenever you add/remove files in the extension target, you may need to do the same in its test target.
What I did which was easier than the other suggestions (no framework creation, no weird settings on build settings, phases, etc) was adding the file that I wanted to test (from the extension target) into the Target Membership of the test target:
The only "drawback" would be that your test target will also include files from your extension (rather than using #testable import like with the main app), but since you are not shipping your test target I would say there is no drawback :)
Tested on Xcode 10.
Note: Only works with Swift code, with ObjC due the BridgingHeader is not possible to follow this approach.

how to config and run objective C test cases in Xcode--XCTest

I was reading the document of XCTest(and personally i think the documentation for this part is not that enough) and I thought I should give it a try for a new project(a MAC command-line project, not and iOS project). and then I faced complaints about linking issues--the test case building failed because the conresponsding class .o(if I am not wrong) files are not found. (the error mes here was not recorded by me, sorry)
Then I wanted to delete the test project and in the end I did not even manage to remove the test project. So seriously, how to remove an exsiting project from the solution if the notion in VS applies here?
After failing at that, I removed the auto-generated test file and created my own test case file and strangely, although Xcode detects the existence of the new test case and test method, the build failed and it failed with no issues--no linking issue, no syntax or whatever issue but it just failed. Now I do not know how to move on now as I do not even get a complaint or an error.
I don't know enough about the state of your project to be certain what the problem is, but here is something to consider: If Xcode added a new build target for your tests, be sure that the .m files that contain the classes you are testing are included in the new build target. You can do this by clicking on the relevant .m file in the Project Navigator and looking at the "Target Membership" in the File Inspector pane. Make sure the box is checked next to the test target.

Unit Testing in With A Static Library

I have an XCode workspace with a user interface project (UI) and a core logic project (Core). I want OCUnit unit tests in the UI project, so I have added a new target for testing, as is commonly done.
I am able to run tests just fine until I put in import statements for classes in the main UI target which in turn reference the Core project.
The error I get is "Lexical or Preprocessor Issue 'xxx.h' file not found". I do not get this message when I build the main UI target directly.
It's as if the main UI target knows about Core when it is built, but when it is referenced from the test target it seems to know nothing about Core.
I took the step of adding a reference to the core project using the "Link Binaries with Libraries" The item in the list remains red. A clue? Maybe, but the red reference in the Link list doesn't keep the UI target from building and using core classes. I also made the main target a dependency of the test target.
Make sure you check out the Apple sample code "Unit Tests":
https://developer.apple.com/library/ios/#samplecode/UnitTests/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011742
Make sure your library project is set as a Dependancy in your OCUnit test target's build phases, AND it's linked as a library.
Open up your project in Xcode. In the File menu, go to Project Settings... (or Workspace Settings... if you are using a workspace). Click Advanced... and make sure Unique is checked. Clean and rebuild.
Check your BUILD_PRODUCTS_DIR to see if the headers for your library show up in there. If they don't, first check the build phases in your library target to make sure the headers you need are in the Public section (the Project section may work as well, but try Public and see if that solves your issue).
That covers the most common problems people seem to run into in your situation. When in doubt, check the target settings in the UnitTests sample against yours. Good luck!
In addition to Jon Reid's answer, I had to do the following as well:
In your test target, go to Build Settings. Set "Always Search User Paths" to YES
In your test target, go to Build Settings. Add the path to your static library headers to Header Search Paths.

Resources