Xcode 7.3 で XCTest が実行できなかった時に試したこと

プログラミングで出逢った出来事

Xcode 7.3 で Cocoa Framework プロジェクトのテストが起動してくれなくなっていたので、再びテストできるようにいろいろ調整してみました。

OS X で使う Cocoa Framework のプロジェクトを Xcode 7.3 で開いてテストを実行しようとしてみたところ、ビルドが終わってテストに移るタイミングで、次のようなエラーが発生して進めませんでした。

Test target ESSwim (OSX)Tests encountered an error (Early unexpected exit, operation never finished bootstrapping - no restart will be attempted)

Xcode のコンソールログを確認すると、次のようなメッセージが表示されていました。どうやらユニットテストで使うフレームワークの一部が読み込めていない様子です。

2016-04-04 19:49:00.734 xctest[12002:1218682] The bundle “ESSwim (OSX)Tests” couldn’t be loaded because it is damaged or missing necessary resources. Try reinstalling the bundle.
2016-04-04 19:49:00.735 xctest[12002:1218682] (dlopen_preflight(/Home/tomohiro/Library/Developer/Xcode/DerivedData/ESSwim-bxuwhfjbkpkixoeeobxvpkzfrula/Build/Products/Debug/ESSwim (OSX)Tests.xctest/Contents/MacOS/ESSwim (OSX)Tests): Library not loaded: @rpath/ESTestKit.framework/Versions/A/ESTestKit
  Referenced from: /Home/tomohiro/Library/Developer/Xcode/DerivedData/ESSwim-bxuwhfjbkpkixoeeobxvpkzfrula/Build/Products/Debug/ESSwim (OSX)Tests.xctest/Contents/MacOS/ESSwim (OSX)Tests
  Reason: image not found)
Program ended with exit code: 82

実際、ログに表示されているフレームワークを適切に読み込めるようにすることでテストを実行できるようになったのですけど、手持ちのプロジェクトによっては同じ対処の仕方では対応できないものもあったりしました。

具体的になぜ対応がばらばらになるのかまでは詳しく探っていないながら、とりあえず各プロジェクトでテスト実行にこぎつけられた方法について、記しておこうと思います。これらのどれか、または幾つかを組み合わせて設定することで、

ちなみに今回、テスト実行時にうまく見つけられなかったフレームワークは CocoaPods でインストールされたフレームワークのようでした。それをテストで使えるようにすることが、今回の着眼点になっていそうな気がします。

1. フレームワークをバンドルする

そのひとつの方法が、見つからないフレームワークをテストターゲットのバンドル内にコピーする方法の様子です。設定はテストターゲットBuild Phases で行います。

目的のフレームワークを、あらかじめ Build Phases の Link Binary With Libraries に登録した上で、自分で作成した Copy Files Build Phases にもそれを追加します。複数のフレームワークがある場合は、それらをすべて登録します。

この時、自分で作った Copy Files Build Phases は DestinationFrameworks にしておく必要があります。

2. Runpath Search Paths を調整する

他にもテストターゲットBuild SettingsRunpath Seatch Paths を調整する必要がある場合もあるようでした。

手持ちの一部のプロジェクトで、この Runpath Seatch Paths 設定が @loader_path/Frameworks になっているのがあって、これを @loader_path/../Frameworks に変更したところ、テストできるようになったプロジェクトがありました。

3. テストターゲットにも Pods をインストールする

たしか以前は動いてくれてた気がするんですけど、とりあえず今日の Xcode 7.3 で知った限りでは、CocoaPods でインストールするフレームワークでテストでも使うものについては、テストターゲット側にもインストールする必要があるようでした。

source 'https://github.com/CocoaPods/Specs.git'

use_frameworks!

def pods

    pod 'ESNotification'

end

target :CodePiece do

    platform :osx, '10.11'
    pods

end

target :CodePieceTests do

    platform :osx, '10.11'
    pods

end

4. クリーンビルドする

他にも、次のようなエラーでテストまでこぎつけないプロジェクトもありました。

building file list ... rsync: link_stat "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/libswiftSecurity.dylib" failed: No such file or directory (2)

これについては以前に こちら で記したのと同じ問題のようでしたけど、とにかくそういう場合は K で実行できる Clean Build Folder... を実行することで解消してくれる様子でした。

ちなみに少なくとも今回の場合、通常の Clean だけでは解消されませんでした。

おしまい

以上のような操作をして、手持ちのプロジェクトを Xcode 7.3 でテストできるようになりました。もしかすると他のケースもありそうですけど、ひとまずはこんな辺りを気にしてみると上手くいったりするかもしれません。