XCTest for existing project - ios

I have a big(about 700 modules) iOS project. Now I need to make unit tests for existing code(before we didn't use it). I've added new XCTest test target for my target and started to write my first test. But after compilation I've got some link errors, because modules from my project weren't be included to test target. Have I include all my modules to test target? Or there is easier way to make test target?

Application files DO NOT need to be included within XCTest targets. Only test files should be included within the 'Compile Sources' list for your XCTest target.
Follow the Apple instructions to add XCTest to your project.
Within the Application target, make sure the compiler option "Symbols hidden by default" is set to NO.
Here is a blog post with screenshots if you get stuck!

Related

What targets should I be adding my files to in my xcode project

I'm working on an xcode app using swift and xcode 8.1.
I keep adding files such as pictures and .plist files to my main folder with my storyboard, but each time it asks what targets I want to add it to. Should I be adding it to my test targets as well? If so, why? Whats the rule to know what targets to add it to.
No, you shouldn't add your files to the test target. Unit test target has access to your application files anyway.
According to the Apple documentation, target is a single build artifact. Because of that, you should only add the files which are building blocks of a specific target.
A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace. A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product. Projects can contain one or more targets, each of which produces one product.
For the most basic scenario with one application target and two test targets the general rule is as follows
Add application classes to the application target.
Add unit test case classes to the unit tests target.
Add UI test classes to the ui tests target.
In more complex scenarios you can have more targets in your application. You can have iMessage extension, share extension etc. You can also have multiple targets for building variants of the same applications but the general rule stays the same.

Can't access swift files in Unit test target in Xcode

Adding swift files to test target will work, but it is not the best way to do. My problem is I can't able to access Swift file whereas Objective-C files are accessible.
I have checked product module name and set configuration file same as project file for test target. Even removed the test target and readded, but, still encountering "Use of undeclared type in SlideViewController".
Can anyone help me with solving this issue?
By default you won't be able to access internal classes from your unit test target.
The apple docs on writing tests with swift say that you need to take two steps to get around this:
Set the ENABLE_TESTABILITY build setting to YES.
Add #testable to the import statement for your module. #testable import MySwiftApp
If you follow both of those steps your SlideViewController (as long as it is not a private class) should be accessible from your unit test file as if it was declared as an open class.
Try to add this on top of your test file:
#testable import <YOUR_MODULE_NAME>
Sometimes you will need to add files to the build phases of your test target.
1.- Go to project navigator
2.- Select your project
3.- On the project and target list, select the target for your tests (Ex. "MyProjectTests")
4.- Select Build Phases tab
5.- Open "Compile Sources"
6.- Using the plus sign, add the files needed for the compilation

How to import XCTest suite

I've created my project without XCTest support.
But now after long time development i want to cover my project with unit tests. And i want do it with XCTest.
How to import XCTest suite into existing project previously created without XCTest support ?
You can add new Unit/UI test case classes through "file-> new-> file -> UI test case class or Unit test class". Make sure that the target membership is set for only the test target and not the regular targets (you can see that in the file inspector). If you currently have no test target, you can add that through "file -> new -> target -> iOS UI testing bundle or iOS Unit Testing Bundle" and add relevant files to the this target.
Adding XCTest target to an existing project is simple you can refer
https://automationwithaditya.wordpress.com/2017/08/21/getting-started-to-xctest-automation-framework/
or follow the steps
1. Click on project
2. Add the target choose the one which you want.
Follow this image

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.

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