Xcode Unit Testing missing certain project classes - ios

I'm attempting to write some unit tests. But, somehow, some classes are found and others are not.
Their targets are the same as is seemingly everything else. And yet some classes I can use and others are not found.
I have #testable import MyProject at the top of course.
In my image below you can see what I mean. Of two classes of the same grouping only one is being recognized:

Double-check and ensure that your file has the correct Target Membership

Fixed by adding an import statement for the class to the Swift bridging header.

Related

#testable import moduleName not importing everything

I have a project that is mixed Obj-C and Swift and I am having some issues getting my unit tests to work.
I'm using the #testable import moduleName directive to import my files, however it does not appear to be importing all the files. I have full access to pretty much all of my Obj-C models, manager classes etc. but none of the view controllers (95% of which are in Obj-C) are available from within the XCTestCase, along with all of my Swift files.
I have imported #testable import ModuleName at the top of the XCTestCase,
I have also edited the target to enable testability, but the only way I can access these files seems to be if I set the files target membership manually, which if I have understood everything correctly, I should not need to do.
Any suggestions?
Yeah I just also went from the same problem about the Unit testing with the project having both Objective-C & Swift languages.
So basically what i found was
You have to add the respective file and all the required files to Test target. And also required to add them to the Bridging_Header to access those files
Moreover the reason behind using the
#testable
is to test methods internal .... methods.
#testable import moduleName
This is used for the purpose of visibility of methods, i.e like internal methods can now be visible in unitTest but atill private methods won’t.

Core Data classes not generated for test target

I use Core Data's automatically generated classes. My project has 3 targets in addition to the test target. For each target, the Core Data classes are properly generated which I verified by inspecting the Derived Data folder. However, classes are not generated for the Test Target despite it being ticked in the Core Data model file. This causes an "undeclared identifier" and "Use of undeclared type" errors when I try to reference one of the Core Data classes in the test target. How can I fix this please?
You do not need extra classes generated for each test target - your import process should import everything, and no files should need to be added to other targets.
Declaring #testable import MyProject should take care of everything.
In Objective C
#import MyProject;
In Xcode 9.1 try adding your .xcdatamodel to a test target too. All auto-generated class will be imported too.
This was due to a bug currently in Xcode (8.3.1) where auto-generated NSManagedObject classes (codegen set to "Class Definition") cannot be found on the global path despite the project compiling successfully. The only way around it is to which to manual generation of the NSManagedObject classes by setting codegen for each entity to "Manual/None".
Select the test target, navigate to Build Settings and search for the setting "Header Search Paths"
Then add the following entry:
$CONFIGURATION_TEMP_DIR/{Project Target Name}.build/DerivedSources/CoreDataGenerated/{Project Name}
Replace the curly brackets with your main target name (not the test target), and your project name, respectively.
Xcode should now be able to find the generated source files when building the test target.
I noticed in Xcode 9.1 that the Data Model Inspector has a drop down for the Module to use. Selecting 'Current Product Module' with the Class Definition Codegen, and including the model in your Test target, compiles without errors. From what I can tell, the problem pieSquared noticed doesn't appear to be an issue, but my tests aren't exhaustive yet. It may be something to try, nonetheless.
I have wrestled with this issue ever since Xcode 9.4 or thereabouts. The error was always the same:
Testing cancelled because build failed.
'MyEntity+CoreDataProperties.h' file not found
I've filed a bug report (45802900), but I got Apple Support involved as well and together we finally found the solution. . Actually, there are two solutions.
Solution 1: Set the Header Search Paths build setting of the Test Target
The most elegant solution, to my mind, is to set the Header Search Paths build setting of the test target. Ziqiao Chen of Technical Support figured out the correct path, while I provided the build variables. For projects with only one data model, the name of which is the same as the project (which is the default), the Header Search Path may be:
$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources/CoreDataGenerated/$(PROJECT_NAME)
Make sure the path is set to 'non-recursive'.
For projects with multiple data models, a non-recursive path should be added to Header Search Paths for each data model:
$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources/CoreDataGenerated/dataModel1
$(TARGET_TEMP_DIR)/../$(PROJECT_NAME).build/DerivedSources/CoreDataGenerated/data_model_B
Solution 2: Add the data model to the Test Target
Another solution, which Ziqiao Chen came up with and which I've also read on here on SO, is to add the data model to the test target. In my experience, however, this only works with a single data model. As Ziqiao Chen pointed out, Xcode should generated the exact same files for the test target as for the main target.
My experience is that in more complicated projects (multiple targets, multiple data models) all kind of linker errors may occur, from complaints about duplicates to the "testing cancelled" error described above. For simple projects, however, it's a quick and simple solution.
For Xcode 11.5:
if Codegen property is class Definition, and if you are not getting a suggestion for the entity you created in xcdatamodel. Try to quit Xcode and reopen your project again. It works for me. This answer is only if you are not getting suggestion but if your file doesn't get generated try any above answer.

Cannot see Swift classes from test target

I have an iOS app using both ObjC and Swift code. I tried setting up a test target for it today with no success. I have a single test case class written in Swift. I imported my app's module there. I made sure the classes I am trying to access are public. But I cannot see them from my test target. I can see ObjC code from there though.
I tried the exact same steps on a dummy project and there it worked fine.
I don't want to add the classes for testing to the test target's compile sources. I am also using Xcode 6.3 and updating to Xcode 7 is not an option for me at the moment.
Any ideas on what I am doing wrong?
Make sure your import is marked with a #testable annotation. For example, you want:
#testable import myprojectname
as opposed to:
import myprojectname
The issue went away after deleting and recreating the test target.

Adding Swift files to test target not fixing unit tests

I have looked at a lot of blogs and tried many things to get my Swift unit tests to work in Xcode 6.0.1 (or 6.1 for that matter). I'm trying to access classes in my app's target so I wrote this line:
var vc: LoginViewController!
Of course, I get the "Use of undeclared type 'LoginViewController'" error.
I then try to add LoginViewController to my test target, but then I get "use of unresolved identifier" errors on other classes in my project. So I try to add those classes to my test target, but I end up with a seemingly endless source of errors like the screenshot below:
Declaring all my classes as public, causes other errors and seems like bad practice. Is there anyway to include unit tests in a Swift project that relies on many frameworks and classes? I simply want to start with something almost exactly like the code in this article.
After much headache and putting this on the back burner, I found that the main problem was when adding files to the test target membership, the Objective-C classes would still complain. I figured it was an old compatibility issue with the new way Swift does unit tests, but the solution was my test target didn't know there was a bridging header. Thus, I added a reference to it in my test target's build settings, like so:
It seems simple and obvious now, but the errors were unhelpful. No other solutions I saw for Swift unit tests suggested this could be an issue, but now I know.
Tl;dr
For unit tests to work in Swift, the test target must know everything the app target knows, so add a reference to your bridging header in your test target too (if applicable).
If you're using Xcode 7, there's now a much better way of dealing with this using #testable import {ModuleName}.
Just make sure that the module you want to test has the build setting Enable Testability set to YES.
I am using Xcode 6.1
You need to add your swift file to the target membership of the test target

Link framework against App and Test Target

I have a custom Framework I use within my normal App target as well as the corresponding UnitTest target. Turns out that confuses the runtime in such way that it is unable to choose the correct implementation since it has multiple choices:
objc[35580]: Class AClass is implemented in both ../MyApp.app/MyApp and ../MyApp.app/MyAppTests. One of the two will be used. Which one is undefined.
That of course leads to weird behavior if you try to check an object's class hierarchy or do any other class related checks.
So it boils down to the following two questions:
I don't see similar logs for e.g. UIKit components, but this framework is also linked to both targets. Have I incorrectly compiled the framework?
Is it just a trivial configuration issue I missed?
PS: I already checked similar posts like 1 or 2, but although everything is configured as described, the problem remains.
You have added the dependency framework to the Tests target. This is flawed thinking. Since your primary application ALSO exports the SAME framework you will receive warnings about duplicated symbols for any classes found in the framework.
By removing your framework from the test target you can resolve the warnings. Remember, you're not losing any functionality by not linking against the same framework in the test target. Trust me, your code is still there.
I ran into a similar problem here: Xcode5: creating new testing target
The key is to create a new unit testing bundle, point it to your original target, and then don't do anything else! If you start including frameworks and source files into the test target, it'll generate these linking errors. The test target is supposed to "inject" the test classes into the actual target, not create a new separate target on it's own. So you just need to import the header files in your test class, and write your test cases.
I think the bundle should only "read" the framework's header files but not build the sources and leave that task to the App (remove the Framework .m files from the UnitTest target).
Right now the App and the UnitTest are both building the Framework, thus the duplicated classes.

Resources