📜 ⬆️ ⬇️

Setting up Unit tests in mixed Swift + Objective-C projects

This article will be small, I’ll tell you what problems arose when creating a target for testing in a mixed and fairly old ObjectiveC + Swift project, and how I managed to solve them.

The first thing that is confusing: an error in one test target can affect the launch of an autotest from another test target. You can add any number of targets for testing in the project, they are usually based on the main target of the project, and are automatically added to its launch scheme. Thus, when running any autotest on this scheme, the rest will compile, and an error on one of the test targes will interfere with the launch of the others. To isolate this effect, you can create different schemes for different test targets.

I will attach a very trivial screenshot, for illustration purposes only:


')


The next problem is the dependencies between Objecive-C and Swift.
In your project is created:

MyProject-Bridging-Header.h : this file contains the names of the ObjectiveC-header files used in swift.
MyProject-swift.h : it creates implicitly the code for the swift classes used in ObjectiveC classes.
MyProject-Prefix.pch : the precompilation file can also contain dependencies in different ways, including constructions like:

#ifdef __OBJC__ #import "MyProject-Swift.h" #endif 

Your autotests can also create such dependencies. When adding the first swift file, Xcode offers to create a bridge-header file for this test target. It all works like a charm. In theory, the contents of the bridge-header autotest should complement the main bridge, but in fact, a replacement occurs. Therefore, in order to have access to all classes of the project in the autotest, in this option I specify the bridge-header of the main target (picture above).

Go to Xcode Target -> BuildSetting and check the following parameters:
Objective-C Bridging Header
Objective-C Generated Interface Header Name
Specify the main target files.

However, if you pull the main bridge-header, then all the dependencies begin to stretch. Therefore, you must also fill in the following parameters with data from the main project:
Framework search paths
Header search paths
Library search path
Other linker flags
Runpath Search Paths do NOT need to be changed.

Then another strange problem was discovered:
For some reason, in older projects, the test target is assigned the same Product Module Name as the main one. This did not stop the lone ObjectiveC, but when adding swift to the project, two problems arise.

The first problem is that in this case

 @testable import MyProject 

the autotest file is ignored and you cannot access Swift classes.

The second problem is that such a target at compilation overwrites the MyProject-swift of the main target and prevents other targets from compiling. This parameter needs to be renamed.

On this, my autotest started and was able to use the project files, which I also wish for you!
I do not often work on setting up a project, so all practical comments and advice on this topic are welcome.

Thank you to everyone who read it.

Source: https://habr.com/ru/post/460961/


All Articles