Xcode 4.6.3からXcode 5.0.2にプロジェクトを移行中です。プロジェクトのユニットテストは、SenTestingKit/OCUnitを使用して開発されました。 Xcode 5でテストを実行しているときに、RunUnitTests
スクリプトからエラーが表示され、
RunUnitTestsは廃止されました。
おそらく関連しているのは、Xcode 5リリースノートのこのノートです。
SenTestingKitとOCUnitは非推奨です。 Migratorを使用してXCTestに移動します。
残念ながら、私はこの神秘的な「移住者」についてこれ以上知ることができませんでした。おそらく私のgoogle-fuに[再び]がないため、主な質問は次のとおりです。ユニットテストをSenTestingKit/OCUnitから新しいXCTestに移行するにはどうすればよいですか( "migrator"の有無にかかわらず)?
移行が複雑なビジネスの場合の2番目の質問:Xcode 5に、まだSenTestingKit/OCUnitに基づいた単体テストを実行させることは可能ですか?結局のところ、これらは単に非推奨になっているだけなので、まだ機能しているはずです。
シャギーフロッグの回答のおかげで、Xcodeのリリースノートに記載されている謎の「移行者」は、「編集」>「リファクタリング」>「XCTestに変換」を選択して起動されるウィザードであることがわかります。このウィザードを使用した経験について、2つのパートで説明します。最初の部分は一次質問に対する不完全な回答であり、2番目の部分は二次質問に対する回答です。
最初に理解する必要があるのは、ウィザードを機能させるために、ユニットテストのターゲットを選択する必要があるということです。メインターゲットが選択されている場合、ウィザードは変換するターゲットをリストしません。
このことを知った後は、ウィザードをステップスルーすることができましたが、私の場合、最終的な結果はまだ壮観な失敗でした!ウィザードは、ソースの変更は不要であり、XCTestに移行するために更新する必要があるのはビルド設定のみであると主張しました。結局、ウィザードはそれを正しく行うことさえできませんでした:それはdidSenTestingKitフレームワークへの参照を削除しましたが、しませんでしたXCTestフレームワークへの参照を入れます。
とにかく、次のリストは、ウィザードが私に代わって作成できなかったために手動で加えなければならない変更のリストです。ウィザードがうまく機能する場合は、これらのすべてを実行する必要がない場合があります。
SenTestCase
からXCTestCase
に変更します<SenTestingKit/SenTestingKit.h>
から<XCTest/XCTest.h>
に変更します。octest
からxctest
に変更します。ST*
からXCT*
に変更します(例:STAssertTrue
はXCTAssertTrue
になります)STAssertEquals
はXCTAssertEqual
に名前を変更する必要があります(末尾の「s」がないことに注意してください)。次のコンパイラ警告が表示された場合は、このことを忘れていることがわかります:warning: implicit declaration of function 'XCTAssertEquals' is invalid in C99
nil
を失敗の説明として渡すことができません。たとえば、XCTAssertNotNil(anObject, nil)
は使用できないため、XCTAssertNotNil(anObject)
に変更する必要があります。このコンパイラエラーが発生すると、この問題があることがわかります:error: called object type 'NSString *' is not a function or function pointer
。NSString
クラスメソッドstringWithFormat:
と同じように、新しいXCTestアサートマクロはフォーマット指定子の定数式を必要とします。このコンパイラエラーが発生すると、この問題があることがわかります:error: expected ')'
。いくつかの例:NSString* formatSpecifier = @"%@";
NSString* failureDescription = @"foo";
// These are OK
XCTAssertNotNil(anObject, @"foo")
XCTAssertNotNil(anObject, @"%@", failureDescription)
// These are not OK
XCTAssertNotNil(anObject, failureDescription);
XCTAssertNotNil(anObject, formatSpecifier, failureDescription);
最後に重要なことですが、すでに上で述べたように、XCTestフレームワークへの参照を単体テストターゲットに追加する必要があります。 Undefined symbols for architecture i386: "_OBJC_CLASS_$_XCTestCase", referenced from: foo
などのリンカエラーが発生した場合は、このことを忘れていることがわかります。
Xcode 6の更新:Xcode 6では、XCTestへのリンクは不要になりました(実際、XCTestは利用可能なフレームワークとしてリストされていません)。代わりに、ビルド設定CLANG_ENABLE_MODULESをYESに設定します(UIでは「モジュールの有効化(CおよびObjective-C)」として公開されます)。これにより、clang
は、#import <XCTest/XCTest.h>
ステートメントを検出すると、XCTestに自動的にリンクします。詳細は clangドキュメンテーションの「モジュール」セクション にあります。
この時点で、XCTestに移行するという私の使命が失敗したことに気付かせるリンカエラーが発生しました。理由:XCTestはSDK 6.1の一部ではありませんが、ベースSDK iOS 6.1( this SO answer はSDK 6.1をXcode 5)。
移行を続行できないため、現時点での私の解決策は、アプリをiOS 7にアップグレードする時間が見つかるまで、SenTestingKit/OCUnitに基づいてユニットテストを維持することです。これは、私がしなければならなかったことです。ユニットテストを実行させるには:
最終的な解決策は、メインターゲットの「実行」または「ビルド」アクションを実行するたびにユニットテストが自動的に実行されるXcode 4.xほど良くありません。残念ながら、「スクリプトの実行」ビルドフェーズなしでは、これを機能させることはできないようです。
編集->リファクタリング-> XCTestに変換
OCUnitテストは引き続き機能しますが、移行することもできます。変更は最終的にはごくわずかです。