使用者從相簿選取圖片後,應用程式可能需要讀取方向資訊、產生縮圖、壓縮原始圖片並上傳;影片還會增加片長、編碼與檔案大小等處理分支。只在開發機上手動操作一次,無法證明下一次建置仍能正確處理同一組輸入。更可靠的做法,是將媒體檔案作為測試夾具納入儲存庫,在雲端 Mac 上重設獨立的模擬器,再使用 simctl addmedia 注入相簿。
先界定要驗證的範圍
這類測試應聚焦於應用程式與系統相簿之間的介面,而不是自動操作系統的「照片」App。建議至少涵蓋以下四條路徑:
- 應用程式能找到預期數量的圖片與影片。
- 選取器回傳後,檔案類型、像素尺寸與影片片長符合預期。
- 壓縮或上傳工作使用原始資源,而不是意外取得的預覽圖。
- 不支援的格式、超大檔案與權限變更能進入明確的錯誤處理分支。
simctl addmedia 適合驗證模擬器中的讀取與處理流程,但不能取代相機拍攝、裝置專用編碼及真實儲存空間壓力測試。將這些界線寫入測試說明,發生失敗時就不會把模擬器的限制誤判為產品缺陷。
回歸測試的目標不是塞入越多素材越好,而是讓每個素材都對應一項可以命名、重複執行與診斷的行為。
準備小型且穩定的媒體夾具
在儲存庫中建立 Tests/Fixtures/Media,只提交測試所需的最小檔案。檔名應表達預期用途,不要使用相機自動產生的名稱。
| 檔案 | 用途 | 主要斷言 |
|---|---|---|
portrait.jpg |
帶有方向資訊的直向圖片 | 套用方向修正後,寬高正確 |
transparent.png |
含透明色版的圖片 | 匯出後透明度未遺失 |
short.mov |
短影片 | 片長與媒體類型正確 |
invalid.txt |
非媒體檔案 | 注入步驟主動拒絕 |
同時儲存 SHA-256 清單,避免夾具被圖片工具無意間改寫:
cd Tests/Fixtures/Media
shasum -a 256 portrait.jpg transparent.png short.mov > SHA256SUMS
shasum -a 256 -c SHA256SUMS
不要在工作執行期間重新編碼夾具。不同系統版本的編碼器可能寫入不同的中繼資料,使問題從「應用程式行為改變」變成「輸入已經改變」。如果確實需要動態檔案,應一併記錄產生指令碼、參數及產生後的摘要。
為每項工作隔離模擬器
共用一部長期執行的模擬器,會留下相簿資源、權限紀錄與背景程序。最簡單的基準做法,是由排程層傳入 DEVICE_UDID,工作開始後關機、清除資料並啟動模擬器,再等待啟動完成:
set -euo pipefail
: "${DEVICE_UDID:?DEVICE_UDID is required}"
: "${BUNDLE_ID:?BUNDLE_ID is required}"
xcrun simctl shutdown "$DEVICE_UDID" 2>/dev/null || true
xcrun simctl erase "$DEVICE_UDID"
xcrun simctl boot "$DEVICE_UDID"
xcrun simctl bootstatus "$DEVICE_UDID" -b
xcrun simctl privacy "$DEVICE_UDID" reset photos "$BUNDLE_ID" || true
xcrun simctl privacy "$DEVICE_UDID" grant photos "$BUNDLE_ID"
模擬器型號與系統版本也應由工作設定固定,不能只寫 name=iPhone,再讓 Xcode 自行選擇。平行工作必須使用不同的 UDID;否則其中一項工作執行 erase 時,另一項工作可能仍在執行測試。
權限測試應拆成兩組:主要流程預先授予相簿權限,以驗證媒體處理;拒絕權限流程則另行執行 revoke,只斷言應用程式的提示與復原入口。不要讓系統彈出式視窗是否出現,決定測試的成敗。
注入素材並執行定向測試
注入前先驗證副檔名與摘要,再將支援的檔案一次交給 addmedia:
FIXTURES="$PWD/Tests/Fixtures/Media"
shasum -a 256 -c "$FIXTURES/SHA256SUMS"
xcrun simctl addmedia "$DEVICE_UDID" \
"$FIXTURES/portrait.jpg" \
"$FIXTURES/transparent.png" \
"$FIXTURES/short.mov"
xcodebuild test \
-workspace Demo.xcworkspace \
-scheme Demo \
-destination "platform=iOS Simulator,id=$DEVICE_UDID" \
-only-testing:MediaImportTests \
-resultBundlePath "$PWD/Artifacts/MediaImport.xcresult"
addmedia 成功傳回,只代表命令接受了檔案,不表示應用程式已經能看見正確的資源。測試程式碼應等待相簿查詢達到預期數量,並設定有限的逾時時間。斷言應優先採用媒體類型、像素尺寸、片長範圍及業務產生的結果,不要依賴系統相簿中的顯示順序,因為匯入時間與資源建立時間可能不同。
如果應用程式會上傳檔案,可以將網路層替換為本機測試實作,記錄收到的 MIME 類型、位元組數與摘要。這樣既能確認讀取的是原始資源,也不會把外部網路波動混入回歸測試結果。
讓失敗結果可以複查
失敗的工作至少應保留三類證據:xcresult、夾具摘要,以及本次執行的裝置資訊。也可以額外輸出目前可用的模擬器清單,但不要收集與問題無關的使用者目錄內容。
常見的誤判與處理方式如下:
- 資源數量比預期多:工作開始前未清除模擬器,或多項工作重複使用同一個 UDID。
- 測試偶爾找不到影片:匯入後立即查詢,沒有等待照片圖庫完成更新。
- 圖片寬高顛倒:程式碼讀取像素尺寸時忽略了方向中繼資料。
- 本機通過、CI 失敗:測試依賴未提交的檔案、預設權限或含糊的 destination。
- 上傳摘要改變:應用程式重新編碼了資源,應分別記錄輸入摘要與上傳內容摘要。
工作結束時關閉模擬器;如果裝置是由目前工作暫時建立,則直接刪除。長期使用的裝置也應在下一項工作開始前重新執行 erase,不要依賴逐項刪除相簿內容。最終檢查項目可歸納為:夾具摘要一致、UDID 獨占、系統版本固定、權限狀態明確、可等待匯入數量達到預期,以及結果套件已封存。做到這些,媒體匯入失敗才會具備穩定的輸入與可供複查的現場資訊。
常見問題
simctl addmedia 可以取代實機相簿測試嗎?
不能完全取代。它適合驗證模擬器中的媒體探索、選取、讀取與上傳;相機擷取、裝置特有編碼及真實儲存壓力仍需安排實機測試。
如何避免多次執行後相簿素材持續累積?
每個任務使用獨立模擬器,注入前先關機並執行 erase,任務結束後刪除暫時裝置,不共用持久化相簿。
在獨享 Apple Silicon 實體節點上執行下一次建置
選擇租用期限與節點區域,確認 Mac Mini M4、16GB RAM、256GB SSD 及應付 USD 金額後提交訂單。