簡體   English   中英

Xcode 4:從命令行運行測試(xcodebuild)?

[英]Xcode 4: Run tests from the command line (xcodebuild)?

我在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時,為我的單元測試包目標設置了測試主機。 我之前看過有關邏輯測試和應用程序測試之間分離的帖子,但似乎Xcode 4消除了這種區別。 我是如何從命令行運行測試的?

重要的提示

使用Xcode 5.1(也許是早期的Xcode), test是一個有效的構建操作。

我們能夠使用test的構建操作和適當的-destination選項調用xcodebuild來替換下面的整個hack。 man xcodebuild獲取更多信息。

以下信息留給了后人


我試圖破解Apple的腳本來運行單元測試

從命令行運行Xcode 4單元測試

Xcode4:從iOS中的命令行運行應用程序測試

網上有很多類似的帖子。

但是,我遇到了這些解決方案的問題。 我們的一些單元測試運行了iOS Keychain,當在errSecNotAvailable攻擊Apple腳本的環境中運行時,這些調用因錯誤而失敗( errSecNotAvailable [-25291]對於病態的好奇)。 結果,測試總是失敗......測試中的一個不良特征。

我根據我在網上其他地方找到的信息嘗試了許多解決方案。 例如,其中一些解決方案涉及嘗試啟動iOS模擬器的安全服務守護程序。 在與這些人掙扎之后,我最好的選擇似乎是在iOS模擬器中運行,充分利用了模擬器的環境。

我做了什么,然后得到了iOS模擬器啟動工具ios-sim 此命令行工具使用私有Apple框架從命令行啟動iOS應用程序。 然而,對我來說特別有用的是,它允許我將環境變量和命令行參數傳遞給它正在啟動的應用程序。

雖然環境變量,我能夠將我的單元測試包注入我的應用程序。 通過命令行參數,我可以傳遞“-SenTest All”以使應用程序運行單元測試並退出。

我為我的單元測試包創建了一個Scheme(我稱之為“CommandLineUnitTests”),並檢查了構建部分中的“運行”操作,如上面的帖子中所述。

不過,我沒有攻擊Apple的腳本,而是將腳本替換為使用ios-sim啟動應用程序的腳本,並設置環境以將單元測試包單獨注入應用程序。

我的腳本是用Ruby編寫的,我比BASH腳本更熟悉。 這是腳本:

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 grunge將它們連接到ios-sim應用程序的一系列命令行參數中。

在底部附近,我從環境中抓取TEST_HOST作為我要啟動的應用程序, system命令實際執行ios-sim傳遞應用程序,命令參數設置環境,參數-SenTest All和測試包路徑到正在運行的應用程序

這個方案的優點是它在模擬器環境中運行單元測試,就像我相信Xcode本身一樣。 該方案的缺點是它依賴於外部工具來啟動應用程序。 該外部工具使用私有Apple框架,因此隨后的操作系統版本可能會很脆弱,但它目前仍然有效。

PS由於敘述的原因,我在這篇文章中經常使用“我”,但很多功勞歸功於我的犯罪伙伴Pawel,他和我一起解決了這些問題。

我受到喬納的帖子的啟發,並找到了一種方法:

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

基本上,你需要Xcode 4,你必須破解腳本才能使它工作,但確實如此。

關鍵點在於說服Xcode 4運行你的iOS測試包,好像它是一個MacOS X包 - 這是平台的一個問題,Xcode不想在命令行上運行開箱即用的應用程序測試。 有趣,因為它似乎工作。

網站上還有一個示例項目。

您正在尋找的是這個未記錄的參數(您確實需要sdk和目標)來從終端運行您的OCUnit測試

xcodebuild  -target MyTarget -sdk iphonesimulator   TEST_AFTER_BUILD=YES

這是一個不完整的解決方案,但我能夠在自己的方案中運行邏輯測試的命令行構建並構建目標: http//blog.carbonfive.com/2011/04/06/running-xcode-4-unit-tests-從最命令行/

xctool解決了這個問題: https//github.com/facebook/xctool

我們在我們的持續集成服務器上使用它沒有問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM