Настройка Unit-тестов в смешанных проектах Swift + ObjectiveC

Данная статья будет маленькой, расскажу, какие проблемы возникли при создании таргета для тестирования в смешанном и достаточно старом проекте ObjectiveC + Swift, и как удалось их решить.
Первое, что сбивает с толку: ошибка в одном тестовом таргете может повлиять на запуск автотеста из другого тестового таргета. Вы можете добавить любое количество таргетов для тестирования в проект, они обычно базируются на основном таргете проекта, и автоматически добавляются в его схему запуска. Таким образом, при запуске любого автотеста на этой схеме, — остальные будут компилироваться, и ошибка на одном из тестовых таргов будет мешать запуску других. Чтобы изолировать это влияние, можно создавать разные схемы для разных тестовых таргетов.

Приложу очень тривиальный скриншот, исключительно для наглядности:

7-u2s3ujfixxgvfywsmcwc-hm0a.png

hsv_s18i78rk5j_cctn4cwm_g2y.png

Следующая проблема — это зависимости между Objecive-C и Swift.
В вашем проекте создается:

MyProject-Bridging-Header.h: в этот файл помещаются названия заголовочных ObjectiveC-файлов, использующиеся в swift.
MyProject-swift.h: создается неявно, код swift-классов, использующихся в ObjectiveC классах.
MyProject-Prefix.pch: файл прекомпилции тоже может содержать зависимости в разных вариантах, включая конструкции типа:

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


В ваших автотестах тоже могут создаваться такие зависимости. При добавление первого swift-файла Xcode предлагает создать bridge-header файл для данного тестового таргета. Работает все это «like a charm». По идее, содержимое bridge-header автотеста должен дополнять основной bridge, но по факту, происходит замена. Поэтому, чтобы в автотесте иметь доступ ко всем классам проекта, я в данной опции указываю bridge-header основного таргета (картинка выше).

Зайдите в Xcode Target → BuildSetting и проверьте следующие параметры:
Objective-C Bridging Header
Objective-C Generated Interface Header Name
Укажите файлы основного таргета.

Однако, если дернуть основной bridge-header, то начинают тянуться все зависимости. Поэтому, нужно также заполнить данными из основного проекта следующие параметры:
FrameWork Search Paths
Header Search paths
Library search Path
Other Linker flags
Runpath Search Paths менять НЕ нужно.

Далее обнаружилась еще одна странная проблема:
По какой-то причине в старых проектах тестовому таргету присваивается такой же Product Module Name, как и основному. Одинокому ObjectiveC это никак не мешало, но при добавлении в проект swift возникают две проблемы.

Первая проблема, в том, что в данном случае

@testable import MyProject


в файле автотеста игнорируется и вы не сможете обратиться к Swift-классам.

Вторая проблема, что такой таргет при компиляции перезаписывает MyProject-swift основного таргета и мешает компилироваться другим таргетам. Этот параметр нужно переименовать.

На этом, мой автотест запустился и смог использовать файлы проекта, чего и вам желаю!
Я не часто занимаюсь настройкой проекта, поэтому все дельные замечания и советы по данной теме приветствуются.

Спасибо, всем, кто дочитал.

© Habrahabr.ru