web-dev-qa-db-ja.com

iOSロジックテストでCocoaPodsを使用するとライブラリが見つからない

私は、私のpodspecのいくつかのライブラリの機能を使用するプロジェクトのクラスに対して、いくつかのiOSロジックテストを作成しようとしています。 Xcodeで提供される標準の単体テストバンドルを使用しています(ただし、アプリケーションテストではなく、単体テストのみ)。

たとえば、Magical Recordを使用しており、podspecでそのライブラリをリンクしています。これは私のワークスペースのPodsプロジェクトにあり、アプリがシミュレーターまたはデバイスで実行されているときに期待どおりに動作します。ただし、Magical Recordを使用するオブジェクトをテストにリンクしようとすると、Magical Recordからセレクターが見つからないというリンカエラーが表示されます。ロジックテストバンドルでHEADER_SEARCH_PATHを更新しようとしました。CocoaPodsが作成したheadersディレクトリにハードコーディングすることもできましたが、運はありません。

CocoaPodsライブラリを使用しないクラスに対してユニットテストを問題なく実行できます。

私はこれについて間違っていますか?コンパイラにCocoaPodsライブラリを表示させるために何か他のことをすべきですか?

148
Mark Struzinski

私は、アプリの主なターゲットがCocoaPodsライブラリから設定をどのように受け取っているかを見て、これを見つけました。 CocoaPodsには、Pods.xcconfigという名前の.xcconfigファイルが含まれています。このファイルには、すべてのヘッダー検索パスが含まれています。

プロジェクトナビゲータでプロジェクトを確認し、[情報]タブをクリックすると、上部のセクションにビルド構成が表示されます。さまざまな構成の開閉用三角ボタンを開くと、メインターゲットの下にポッドが一覧表示されます。ドロップダウンをクリックして、ポッドをロジックテストターゲットにも追加する必要がありました。

Configurations Snapshot

また、メインターゲットから$(inherited)${PODS_HEADERS_SEARCH_PATHS}の設定をコピーし、Build Settings/HEADER_SEARCH_PATHSの下のロジックテストターゲットにコピーする必要がありました。

最後に、論理テストターゲットのライブラリとのリンクバイナリビルドフェーズにlibPods.aを追加する必要がありました。

これが他の誰かを助けることができることを願っています。

174
Mark Struzinski

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以前の回答

使用するのは、Podfilelink_with です。何かのようなもの:

link_with 'MainTarget', 'MainTargetTests'

次に、pod installを再度実行します。

224
Keith Smiley

私がここで見つけた解決策があります CocoaPodsによるユニットテスト

Xcodeでプロジェクトファイルを開き、(ターゲットではなく)プロジェクトを選択します。右側のパネルに[構成]というセクションがあります。テストターゲットの[構成ファイルに基づく]列でポッドを選択します。

enter image description here

53
Mingming

ライブラリをテスト対象にリンクする必要があるという他の回答に同意します。しかし、これまでのところどの提案も私を助けてくれませんでした。 @fabbがコメントに書いているように、「テスト時に、isSubclassOfClass:呼び出しはNOを返し、YESを返す必要があります。これを説明できる唯一の理由は、依存関係が実際にメインターゲットとテストターゲットの両方にリンクされることです。テストターゲットのバンドルローダーがメインバンドルをロードするとき、どのクラスを取るかを決定できません。」このスレッドの以前のすべての提案で同じ問題が発生します。

私が働いた解決策は、Podfileを更新して、メインターゲットとテストターゲットの特定のPodを定義することでした。

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

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

テスト固有のPodを使用しなかった場合でも、テストターゲットのPodを指定することはnecessaryでした。そうしないと、CocoaPodsは必要なリンクロジックをプロジェクトに挿入しません。

このリンク は、私がこの結論に達するのを助けたものです。

18
JRV

アプリケーションテストターゲットでの重複シンボルエラーを回避するために、: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'

アプリケーションのテストターゲットを論理ユニットテストのターゲットに変更すると、リンカーエラーが発生します。 :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
Hai Feng Kao

@Keith Smileyソリューションに従ってlink_withを使用できます。

共通のポッドと各ターゲットの詳細がある場合、「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」を両方のターゲットに追加し、「Typhoon」を「MyProject」ターゲットのみに追加しました

6
Elihay

この問題に対する私の解決策は、Podfileを変更して、このように両方のターゲットにライブラリを含めることでした

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

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

また、Swiftを使用しているため、MyApp-Bridging-Header.hファイルを含めるようにテストターゲットを構成する必要もありました。 (ビルド設定タブの下のSwiftコンパイラグループ内)

5
Qw4z1

いくつかのバージョン管理中にいくつかのライブラリファイルを失ったとき、私は同様の発生がありました。私はまだポッドでライブラリファイルを見ましたが、実際のコードが欠落しているため、XCodeはそれがなくなったと言いました。残念なことに、「pod install」を実行しても、失われたファイルがすぐに元に戻るわけではありません。

次の手順を実行して、ポッドを手動で削除および交換する必要がありました。

  1. Podfileからライブラリを削除します
  2. 「pod install」を実行して、ライブラリを完全に削除します
  3. ライブラリをPodfileに戻す
  4. 「pod install」を再度実行します

これにより、問題のライブラリが元の形式に戻ります。

4
Maxwell

CocoaPods 1.xの時点では、ターゲットと対応するテストターゲットの間の共有依存関係を宣言する新しい方法があります。私はこれまでMark Struzinskiが受け入れたソリューションを使用していましたが、この方法を使用すると、次のテストを実行するときに大量の警告が発生しました。

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

これにより、-Testターゲットは、複数のバイナリコピーなしで、アプリターゲットの依存関係にアクセスできます。これにより、テストのビルド時間が大幅に短縮されました。

2
Darren Black

これを試してみてください、それは私のために働いています、

設定でポッドを設定する必要があります

Xcodeプロジェクト(プロジェクト)のプロジェクト->情報->構成は、デバッグ、リリース(およびそれ以外の場合)。 「ヘッダーが見つかりません-検索パスが含まれていません」 を参照してください

enter image description here

これが誰かの助けになることを願っています。

2
Jaywant Khedkar

libPods.aを2回追加した場合、次のような厄介なエラーが発生することにも注意してください。

232 duplicate symbols for architecture i386

これを修正するには、プロジェクトエクスプローラーでlibPods.a参照の1つを削除するだけです。

2
Mat Ryer

IOSでSwiftアプリを使用してGoogleMaps Objective-C PODの統合を行っているため、問題はテストターゲットがブリッジヘッダーファイルへの参照を持っていなかったことです(Swift_OBJC_BRIDGING_HEADERビルド設定で)。 Swift単体テストでサードパーティAPI呼び出し(マップAPIなど)を使用できるように、アプリとテストアプリの両方のターゲットがそれを指していることを確認してください。

1
appledevguru

次の構文は私にとって最高の結果をもたらします(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

これがないと、重複シンボルに関するテスト実行中に警告が表示されます。

この警告が消えた後。

0

XCTestでOpenCVを使用すると問題が発生しました。 Undefined symbols for architecture arm64のようなクラスでは、cv::Matのリンカーエラーが発生していました。メインターゲットの下でpod 'OpenCV', '~> 2.0'を使用して、CocoaPodsからOpenCVをインストールしています。 OpenCV依存関係をテストターゲットの下に置くか、inherit! :search_pathsを使用しようとしても、どれもうまくいきませんでした。解決策は、次のようなabstract_targetを作成することでした。

# Uncomment the next line to define a global platform for your project
platform :ios, '6.1.6'

abstract_target 'Shows' do
  pod 'RMVision', path: '../..'
  pod 'RMShared', path: '../../../RMShared'
  pod 'OpenCV', '~> 2.0'

  target 'RMVisionSample' do
    # Uncomment the next line if you're using Swift or would like to use dynamic frameworks
    # use_frameworks!

    # Pods for RMVisionSample
  end

  target 'RMVisionSampleTests' do
    # inherit! :search_paths
    # Pods for testing
  end

  target 'RMVisionBenchmarks' do
    # inherit! :search_paths
    # Pods for testing
  end

end 

また、プロジェクトをクリーンアップし、テスト時に新しいものを開始するのに役立つpod deintegratepod cleanコマンドも役立ちます。 [Sudo] gem install cocoapods-deintegrate cocoapods-cleanを使用してこれら2つをインストールできます。

0
Foti Dim