Библиотеки не найдены при использовании CocoaPods с логическими тестами iOS

Я пытаюсь написать некоторые логические тесты iOS против классов в моем проекте, которые используют функциональные возможности некоторых библиотек моего podspec. Я использую стандартный пакет unit test, предоставленный в Xcode (хотя и не тесты приложений, а только тесты модулей).

Например, я использую Magical Record, и у меня есть библиотека, связанная в моем podspec. Он присутствует в проекте Pods в моей рабочей области и работает так, как ожидалось, когда приложение запускается в симуляторе или на устройстве. Однако, когда я пытаюсь связать с тестом объект, который использует магическую запись, я получаю ошибку компоновщика, заявляя, что он не может найти селекторов из Magical Record. Я попытался обновить свой HEADER_SEARCH_PATH в своем комплекте логических тестов, даже жестко кодируя его в каталог заголовков, созданный CocoaPods, но не повезло.

Я могу запускать модульные тесты против классов, которые не используют библиотеки CocoaPods без проблем.

Я собираюсь сделать это неправильно? Должен ли я делать что-то еще, чтобы заставить компилятор видеть библиотеки CocoaPods?

Ответ 1

Я понял это, посмотрев, как основная цель моего приложения получает настройки из библиотеки CocoaPods. CocoaPods включает файл .xcconfig с именем Pods.xcconfig. Этот файл содержит все пути поиска заголовков.

Если вы посмотрите на свой проект в навигаторе проекта и откройте вкладку "Информация", вы увидите свои конфигурации сборки, перечисленные в верхней части. Если вы откроете треугольник раскрытия для своих разных конфигураций, вы увидите подписи, перечисленные под вашей основной целью. Я должен был щелкнуть выпадающее меню и добавить Pods к целевой логической цели.

Configurations Snapshot

Мне также пришлось скопировать настройки $(inherited) и ${PODS_HEADERS_SEARCH_PATHS} из моей основной цели и скопировать их в целевой логический тест в разделе "Настройки сборки /HEADER _SEARCH_PATHS".

Наконец, мне пришлось добавить libPods.a в фазе компоновки ссылок с базой данных для моей цели логических тестов.

Надеюсь, это поможет кому-то другому.

Ответ 2

CocoaPods 1.0 изменил синтаксис для этого. Теперь это выглядит так:

def shared_pods
    pod 'SSKeychain', '~> 0.1.4'
    ...
end

target 'Sail' do
    shared_pods
end

target 'Sail-iOS' do
    shared_pods
end

Предварительно CocoaPods 1.0 ответ

То, что вы хотите использовать, это link_with из вашего Podfile. Что-то вроде:

link_with 'MainTarget', 'MainTargetTests'

Затем снова запустите pod install.

Ответ 3

Существует решение, которое я нашел здесь, модульные тесты с CocoaPods:

Откройте файл проекта в XCode, затем выберите Project (не цель), на правой панели есть раздел под названием Configurations. Выберите "Модули" в столбце "На основе файла конфигурации" для своей цели тестирования.

enter image description here

Ответ 4

Я согласен с другими ответами, говорящими, что необходимо связать библиотеки с тестовыми целями. Однако ни одно из предложений пока не помогло мне. Поскольку @fabb пишет в комментарии: "при тестировании вызовы isSubclassOfClass: возвращают НЕТ, где они должны возвращать ДА. Единственная причина, по которой я могу это объяснить, - это то, что зависимости действительно связаны как с основной, так и с тестовой мишенью, и когда тестовый целевой загрузчик пакетов загружает основной пакет, он не может решить, какой класс взять." Я получаю ту же проблему со всеми предыдущими предложениями в этом потоке.

Решением, которое я получил для работы, было обновление моего подфайла для определения определенных Pods для моей основной цели и моей тестовой цели:

target 'MyTarget' do
   pod 'AFNetworking', '~> 2.5.0'
   pod 'Mantle', '~> 1.5'
end

target 'MyTargetTests' do
   pod 'OCMockito', '~> 1.3.1'
end

Необходимо было указать Pod для моей тестовой цели, даже если я не использовал никаких конкретных тестов. В противном случае CocoaPods не вставили бы логику ссылок в мой проект.

Эта ссылка помогла мне прийти к такому выводу.

Ответ 5

Я добавил :exclusive => true, чтобы избежать дублированных ошибок символов в целевом тестовом приложении.

target 'myProjectTests', :exclusive => true do
   pod 'OCMock', :head
   pod 'XCTAsyncTestCase', :git => 'https://github.com/iheartradio/xctest-additions.git'
end

link_with 'myProject', 'myProjectTests'

Когда я изменил цель тестирования приложения на логический unit test, возникает ошибка компоновщика. После удаления :exclusive => true все будет работать снова.

target 'myProjectTests', do
   pod 'OCMock', :head
   pod 'XCTAsyncTestCase', :git => 'https://github.com/iheartradio/xctest-additions.git'
end

link_with 'myProject', 'myProjectTests'

:exclusive => true указывает, что все внешние do...end НЕ должны быть привязаны к myProjectTests, что является разумным в целевых тестах приложений, но это приведет к ошибкам компоновщика в логических целях тестирования.

Ответ 6

Вы можете использовать link_with в соответствии с решением @Keith Smiley.

Если у вас есть общие контейнеры и особенности для каждой цели, вы можете использовать опцию "def" для определения группы контейнеров. и использовать "def" позже в эксклюзивной цели.

def import_pods
    pod 'SSKeychain'
end

target 'MyProjectTests', :exclusive => true do
  import_pods
end

target 'MyProject', :exclusive => true do
  import_pods
  pod 'Typhoon'
end

в приведенном выше примере, я добавил "SSKeychain" к обеим целям, а "Тайфун" - только к цели "MyProject"

Ответ 7

Мое решение этой проблемы состояло в том, чтобы изменить мой подфайл, чтобы включить библиотеку в обе цели, такие как

target "MyApp" do  
    pod 'GRMustache', '~> 7.0.2'
end

target "MyAppTests" do
    pod 'GRMustache', '~> 7.0.2'
end

И поскольку я использую swift, мне также пришлось настроить тестовый объект, чтобы включить файл MyApp-Bridging-Header.h. (В группе Swift Compiler на вкладке "Параметры сборки" )

Ответ 8

У меня было подобное явление, когда я потерял некоторые файлы библиотеки во время некоторого контроля версий. Я все еще видел файл библиотеки в своих Pods, но с отсутствующим кодом, XCode сказал, что он исчез. К моему ужасу, запуск 'pod install' не сразу возвращал потерянные файлы.

Мне пришлось удалить и заменить блок вручную, выполнив следующие действия:

  • Удалить библиотеку из подфайла
  • Запустите 'pod install', чтобы полностью удалить библиотеку.
  • Поместите библиотеку обратно в подфайл
  • Запустите 'pod install' снова

Это должно вернуть библиотеку в оригинальную форму.

Ответ 9

Также стоит отметить, что если вы добавили libPods.a дважды, вы получите такую ​​неприятную ошибку, как это:

232 duplicate symbols for architecture i386

Чтобы исправить это, просто удалите одну из ссылок libPods.a в Project Explorer.

Ответ 10

Как и в CocoaPods 1.x, существует новый способ объявить общие зависимости между целевым объектом и соответствующим целевым объектом тестирования. Я использовал принятое решение Марк Струзински до этого момента, но с помощью этого метода было получено огромное количество предупреждений при выполнении моих тестов:

Class SomeClass is implemented in both /Path/To/Test/Target and /Path/To/App/Target. One of the two will be used. Which one is undefined.

С CocoaPods 1.x мы можем объявить нашу цель -Test как наследующую через родительские целевые маршруты поиска, например:

target 'MyApp' do
    pod 'aPod'
    pod 'anotherPod'
    project 'MyApp.xcodeproj'
end
target 'MyAppTests' do
    inherit! :search_paths
    project 'MyApp.xcodeproj'
end

Это приведет к тому, что целевая цель будет иметь доступ к зависимостям целевой цели приложения без нескольких двоичных копий. Это серьезно ускорило время сборки тестов для меня.

Ответ 11

Я работаю с интеграцией с GoogleMaps Objective-C POD на iOS с моим Swift-приложением, и поэтому для меня проблема заключалась в том, что тестовая цель не имела ссылки на файл заголовка моста (SWIFT_OBJC_BRIDGING_HEADER) в настройках сборки. Убедитесь, что целевые приложения и тестовые приложения указывают на то, что вызовы API сторонних разработчиков (API карт и т.д.) Могут быть использованы в быстрых модульных тестах.

Ответ 12

Попробуйте это, это работает для меня,

Нам нужно установить блоки в конфигурациях,

Project-> Info-> Configurations в проекте Xcode (ваш проект) должен быть установлен как основной проект 'Pods' для отладки, выпуска (и того, что у вас еще есть). Смотрите "Заголовки не найдены - пути поиска не включены"

enter image description here

Надеюсь, это поможет кому-то.

Ответ 13

Следующий синтаксис дает лучший результат для меня (проверен в соответствии с cocoapod v.1.2.1):

https://github.com/CocoaPods/CocoaPods/issues/4626#issuecomment-210402349

 target 'App' do
    pod 'GoogleAnalytics' , '~> 3.0'
    pod 'GoogleTagManager' , '~> 3.0'

     pod 'SDWebImage', '~>3.7'
     platform :ios, '8.0'
     use_frameworks!

     target 'App Unit Tests' do
         inherit! :search_paths
     end
 end

Без этого у меня есть предупреждения во время пробного запуска о повторяющихся символах.

После этого предупреждения исчезли.