47

Xcode 4 でまったく新しい iOS プロジェクトを作成し、単体テストを含めました。既定のアプリには、メイン アプリケーションと単体テスト バンドルの 2 つのターゲットがあります。「製品 > テスト」(Command-U) を使用すると、アプリケーションがビルドされ、単体テスト バンドルがビルドされ、iOS シミュレーターが起動され、テストが実行されます。今、コマンドラインから同じことをしたいと思っています。コマンド ライン ツール (xcodebuild) には「テスト」アクションはありませんが、アプリケーション自体に依存するため、単体テスト バンドル ターゲットを直接ビルドできるはずです。ただし、実行中:

xcodebuild -target TestAppTests -sdk iphonesimulator4.3 -configuration Debug build

次のメッセージが表示されます。

/Developer/Platforms/iPhoneSimulator.platform/Developer/Tools/Tools/RunPlatformUnitTests:95: warning: Skipping tests; the iPhoneSimulator platform does not currently support application-hosted tests (TEST_HOST set).

GUI から Command-U を実行すると、Test Host が単体テスト バンドル ターゲットに設定されるため、これは嘘のように思えます。ロジック テストとアプリケーション テストの分離に関する以前の投稿を見たことがありますが、Xcode 4 ではその区別がなくなっているようです。コマンドラインからテストを実行する方法の手がかりはありますか?

4

5 に答える 5

48

重要な注意点

Xcode 5.1 (おそらく以前の Xcode も同様)testでは、有効なビルド アクションです。

-destination以下のハック全体を、test のビルド アクションと適切なオプション を使用した xcodebuild の呼び出しに置き換えることができました。man xcodebuild詳細については。

以下の情報は、後世のためにここに残されています


で述べたように、単体テストを実行するためにAppleのスクリプトをハッキングしてみました

コマンドラインから Xcode 4 単体テストを実行する

Xcode4: iOS のコマンドラインからアプリケーション テストを実行する

および多数の同様の投稿がウェブ上で行われています。

ただし、これらのソリューションで問題が発生しました。単体テストの一部は iOS キーチェーンを実行し、それらの呼び出しは、Apple のスクリプトをハッキングした環境で実行すると、エラー ( errSecNotAvailable[-25291] 病的好奇心) で失敗しました。その結果、テストは常に失敗しました... テストの望ましくない機能です。

Web 上の他の場所で見つけた情報に基づいて、いくつかの解決策を試しました。これらの解決策のいくつかには、たとえば、iOS シミュレーターのセキュリティ サービス デーモンを起動しようとする試みが含まれていました。それらに苦労した後、私の最善の策は、シミュレーターの環境を最大限に活用して iOS シミュレーターで実行することであると思われました。

私がしたことは、iOS シミュレータ起動ツールios-simを理解することでした。このコマンド ライン ツールは、Apple のプライベート フレームワークを使用して、コマンド ラインから iOS アプリケーションを起動します。しかし、私にとって特に役に立ったのは、環境変数とコマンド ライン引数の両方を起動中のアプリに渡すことができるという事実でした。

環境変数を使用して、単体テスト バンドルをアプリケーションに挿入することができました。コマンド ライン引数を使用して、アプリで単体テストを実行して終了するために必要な "-SenTest All" を渡すことができます。

上記の投稿で説明されているように、単体テスト バンドル用のスキーム (「CommandLineUnitTests」と呼びます) を作成し、ビルド セクションで「実行」アクションを確認しました。

ただし、Apple のスクリプトをハッキングするのではなく、ios-sim を使用してアプリケーションを起動し、単体テスト バンドルをアプリケーションに個別に挿入する環境をセットアップするスクリプトに置き換えました。

私のスクリプトは、BASH スクリプトよりも慣れ親しんだ Ruby で書かれています。そのスクリプトは次のとおりです。

if ENV['SL_RUN_UNIT_TESTS'] then
    launcher_path = File.join(ENV['SRCROOT'], "Scripts", "ios-sim")
    test_bundle_path= File.join(ENV['BUILT_PRODUCTS_DIR'], "#{ENV['PRODUCT_NAME']}.#{ENV['WRAPPER_EXTENSION']}")

    environment = {
        'DYLD_INSERT_LIBRARIES' => "/../../Library/PrivateFrameworks/IDEBundleInjection.framework/IDEBundleInjection",
        'XCInjectBundle' => test_bundle_path,
        'XCInjectBundleInto' => ENV["TEST_HOST"]
    }

    environment_args = environment.collect { |key, value| "--setenv #{key}=\"#{value}\""}.join(" ")

    app_test_host = File.dirname(ENV["TEST_HOST"])
    system("#{launcher_path} launch \"#{app_test_host}\" #{environment_args} --args -SenTest All #{test_bundle_path}")
else
    puts "SL_RUN_UNIT_TESTS not set - Did not run unit tests!"
end

コマンドラインからこれを実行すると、次のようになります。

xcodebuild -sdk iphonesimulator -workspace iPhoneApp.xcworkspace/ -scheme "CommandLineUnitTests" clean build SL_RUN_UNIT_TESTS=YES

環境変数を探した後SL_RUN_UNIT_TESTS、スクリプトはプロジェクトのソース ツリー内で「ランチャー」(iOS-sim 実行可能ファイル) を見つけます。次に、Xcode が環境変数で渡すビルド設定に基づいて、ユニット テスト バンドルへのパスを構築します。

次に、単体テスト バンドルを挿入する、実行中のアプリケーション用の一連のランタイム環境変数を作成します。これらの変数をenvironmentスクリプトの途中でハッシュに設定し、Ruby グランジを使用してそれらをアプリケーションの一連のコマンド ライン引数に結合しios-simます。

下部近くで、TEST_HOST起動するアプリとして環境からを取得し、system実際にコマンドを実行ios-simして、アプリケーション、環境を設定するためのコマンド引数、-SenTest All実行中のアプリケーションへの引数とテスト バンドル パスを渡します。

このスキームの利点は、Xcode 自体が実行していると私が信じているのと同じように、シミュレーター環境で単体テストを実行できることです。この方式の欠点は、アプリケーションの起動を外部ツールに依存することです。この外部ツールはプライベートな Apple フレームワークを使用するため、その後の OS リリースでは壊れやすいかもしれませんが、現時点では機能します。

PS この投稿では、物語上の理由から「私」を多用しましたが、多くの功績は、私と一緒にこれらの問題を解決してくれた犯罪のパートナーであるパウエルに捧げられています。

于 2012-05-30T20:06:28.127 に答える
9

私はジョナの投稿に触発され、それを行う方法を見つけました。

http://longweekendmobile.com/2011/04/17/xcode4-running-application-tests-from-the-command-line-in-ios/

基本的に、Xcode 4が必要であり、それを機能させるにはスクリプトをハックする必要がありますが、それは可能です。

重要な点は、iOSテストバンドルをMacOSXバンドルであるかのように実行するようにXcode4を説得することです。これはプラットフォームの問題です。Xcodeはコマンドラインですぐにアプリケーションテストを実行することを望んでいません。おかしい、それはうまくいくようだから。

サイトにはサンプルプロジェクトもあります。

于 2011-04-17T19:42:50.477 に答える
5

これは不完全なソリューションですが、ロジック テストのコマンド ライン ビルドを独自のスキームとビルド ターゲットで実行することができました: http://blog.carbonfive.com/2011/04/06/running-xcode-4-unit-tests-コマンドラインから/

于 2011-04-06T20:45:09.953 に答える
3

xctool はこの問題を解決します: https://github.com/facebook/xctool

問題なく継続的インテグレーションサーバーで使用しています

于 2013-06-21T06:46:13.800 に答える