加快 iOS 測試的腳步— build-for-testing + test-without-building

Vivian Liu
AppDev Ooops
Published in
5 min readJul 26, 2019

看到 Apple 在 WWDC 2019 的 Testing in Xcode 又提到了 build-for-testing 以及 test-without-building 的使用,因此,決定來分享一下我們是如何套用 build-for-testing 及 test-without-building 來加速我們 iOS 的自動化測試!

相信很多人都跟我們一樣,不管是在 local 或是在 CI 上要執行測試都是使用這種方法:

$ xcodebuild test \
-workspace MyApp.xcworkspace \
-scheme TestScheme \
-only-testing:MyAppUITests/DemoTest/testDemo \
-destination "platform=iOS Simulator,OS=12.1,name=iPhone XS" \
-derivedDataPath 'output/'

然而 xcodebuild test 實際上會做的事情是「build + test」,所以當你這次測試結束後想要換一台裝置跑時,又會需要再一次的「build + test」時間,如此一來裝置越多就會導致整趟流程越久,這對於我們來說不是一件樂見的事情。那有什麼辦法能讓我們在不同 iPhone 上分別執行測試時不需要再多等 build 的時間呢?有的,那就是使用 build-for-testing + test-without-building

Build-for-testing

build-for-testing 這個指令在做的事情就只有 building,會 build 出給測試用的 app 以及一個 .xctestrun 的檔案。範例如下:

$ xcodebuild build-for-testing \
-scheme TestScheme \
-workspace MyApp.xcworkspace \
-destination 'generic/platform=iOS Simulator' \
-destination 'generic/platform=iOS' \
-derivedDataPath 'output/'
  • -destination:有兩個參數分別為 generic/platform=iOS Simulatorgeneric/platform=iOS,前者 build 出的產物是出給 simulator 執行,而後者則是給實體裝置執行
  • -derivedDataPath:要帶入的參數為你 build 出來的產物要放的路徑

Test-without-building

test-without-building 這個指令在做的事情就只有 testing。他會照你後面給的參數來執行對應的測試,除了 test改成 test-without-building-scheme-workspace改成 -xctestrun外其他設定都跟 xcodebuild test相同。範例如下:

$ xcodebuild test-without-building \
-xctestrun MyAppUITests_iphonesimulator12.1-x86_64.xctestrun \
-destination "platform=iOS Simulator,OS=12.1,name=iPhone XS" \
-only-testing:MyAppUITests/DemoTest/testDemo \
-resultBundlePath 'results/'
  • -xctestrun:帶入執行測試對應的裝置需要的 .xctestrun 檔案。如果你要執行在 simulator 上,則需帶入名稱內有 iphonesimulator 的 .xctestrun 檔案;反之,如果要執行在實體裝置上,則需帶入名稱內有 iphoneos 的 .xctestrun 檔案

實際運用

我們在 CI 上遵照了跟手動測試一樣的原則:「如果連最基本的 acceptance criteria 都無法滿足,就無需繼續執行測試下去」,所以會依照 test case 對整體的重要性及特性來分配到不同的 stage 上執行,因此我們在 CI 上總共有 7 個 stage,實際上是如何細分的就不在這裡贅述了。

若是使用最一開始 xcodebuild test 的方式執行測試,總測試時間就會是(build time) * 7 + total testing time ,而對我們而言這樣總共會需要花費 4 小時 15 分鐘 47 秒

如果改成使用這篇所提到的 build-for-testing 以及 test-without-building ,總測試時間就只會是 (build time) * 1 + total testing time ,而我們只需要花費 2 小時 51 分鐘 19 秒 ,如果再搭配上 Jenkins pipeline 的 parallel,整體測試時間則可以降低成 1 小時 40 分鐘 8 秒 ,比一開始所花費的時間足足節省了 2 小時 35 分鐘 39 秒

總結

使用 build-for-testing + test-without-building 真的減少了我們很多測試及 demo 時間,真心推薦大家來使用!如果想了解更多相關的內容可以參考 WWDC 在 2016 發表的影片 Advanced Testing and Continuous Integration

--

--