訂單確認頁在預設字級下,地址和提交按鈕都能完整顯示;但使用者把 iPhone 文字放大後,按鈕卻被底部固定列擋住了。只在開發用裝置上開啟頁面一次,很容易漏掉這類問題:動態字級改變的不只是文字大小,還包括換行位置、儲存格高度和可捲動範圍。以下會在雲端 Mac 的 iOS 模擬器上固定測試條件,再用介面測試檢查關鍵操作路徑。
先確定測試對象與通過條件
選一個真實且內容較長的頁面,例如訂單確認、設定詳情或錯誤說明。記錄專案的 Xcode 工程、scheme、模擬器裝置、iOS 執行階段和測試帳號狀態;後續比較都必須使用同一組條件。如果雲端 Mac 由多人共用,請為這項測試指定獨立的模擬器裝置,避免其他工作變更文字大小或清除 App 資料。
先列出使用者在頁面上必須完成的操作,再撰寫斷言。建議至少涵蓋標題可閱讀、主要按鈕可操作、長篇說明可捲動至末尾,以及返回操作可用。只檢查檢視是否存在,並不足以證明文字沒有被裁切。
| 檢查對象 | 可執行的通過條件 | 需人工複核的現象 |
|---|---|---|
| 頁面標題 | 找得到預期的輔助使用識別碼 | 換行後是否蓋住相鄰內容 |
| 主要操作 | 捲動後可點擊並進入預期狀態 | 按鈕文字是否完整 |
| 長篇說明 | 末段內容可捲動至可見區域 | 文字或容器邊緣是否遭到裁切 |
把「看起來正常」拆成可實際操作的路徑,以及需要檢視的截圖。自動斷言負責攔下明確的故障,截圖則用來發現尚未寫成斷言的視覺問題。
固定模擬器並切換文字大小
先在雲端 Mac 上確認 Xcode 命令列工具指向預期版本,再列出可用裝置。不要假設 booted 永遠是同一台裝置:同一台 Mac 上的平行工作可能啟動多個模擬器。將目標裝置的 UDID 寫入測試工作設定,啟動後等待系統完成開機。
xcode-select -p
xcrun simctl list devices available
export SIM_UDID="从上一步选择的设备 UDID"
xcrun simctl boot "$SIM_UDID"
xcrun simctl bootstatus "$SIM_UDID" -b
xcrun simctl help ui
如果裝置已經啟動,boot 會提示目前狀態;確認 UDID 正確後,直接執行 bootstatus 即可。simctl ui 使用的文字大小參數,應依已安裝工具提供的說明確認,不要直接把其他 Xcode 版本接受的級別名稱抄進腳本。將經本機說明核實的級別值傳給測試工作,例如透過環境變數 TEXT_SIZE,再執行:
: "${TEXT_SIZE:?set a supported content size}"
xcrun simctl ui "$SIM_UDID" content_size "$TEXT_SIZE"
xcrun simctl ui "$SIM_UDID" content_size
至少測試預設級別、一個較大的級別,以及產品承諾支援的最大級別。不要只測兩端:中間級別可能剛好讓標題多換一行,卻尚未觸發為最大字級準備的版面配置。每次切換後都重新啟動待測 App,確保目前頁面不是切換前快取的舊狀態。
讓介面測試檢查操作路徑
在 App 中為關鍵控制項設定穩定的輔助使用識別碼,例如 checkout.title、checkout.submit 和 checkout.lastNote。識別碼應代表功能,而不是依賴會隨語言改變的按鈕文字。測試應從相同的初始頁面進入確認頁;若需要登入或準備資料,請使用專案既有的測試環境,不要把真實憑證寫進測試程式碼或日誌。
以下 XCTest 程式片段示範斷言方向;具體的導覽流程和成功狀態識別碼,請依專案實作替換。對於長頁面,先滑動,再判斷末段與按鈕是否可操作:
let app = XCUIApplication()
app.launch()
let title = app.staticTexts["checkout.title"]
XCTAssertTrue(title.waitForExistence(timeout: 10))
let page = app.scrollViews["checkout.content"]
let lastNote = app.staticTexts["checkout.lastNote"]
for _ in 0..<6 where !lastNote.isHittable {
page.swipeUp()
}
XCTAssertTrue(lastNote.isHittable)
let submit = app.buttons["checkout.submit"]
for _ in 0..<6 where !submit.isHittable {
page.swipeUp()
}
XCTAssertTrue(submit.isHittable)
submit.tap()
XCTAssertTrue(app.staticTexts["checkout.success"].waitForExistence(timeout: 10))
如果頁面並非 ScrollView,不要為了讓範例通過而硬套選取器,應依實際容器調整。為滑動次數設定上限,可避免版面損壞時測試無限等待;但「可以點擊」仍無法證明按鈕文字完整,因此也要保留截圖。
保留每個級別的證據並定位故障
每個級別都要記錄裝置 UDID、執行階段、Xcode 版本、文字級別和測試結果。失敗時先儲存介面測試附件,再以相同級別重跑並取得模擬器截圖;檔名應加入級別和頁面名稱,避免平行工作互相覆寫。若使用命令列擷取截圖,可執行 xcrun simctl io "$SIM_UDID" screenshot output.png;實際工作中,應將固定檔名改為專屬的輸出路徑。
檢視截圖時,先從最外層的版面配置找原因。高度固定的標題容器常會讓第二行文字消失;水平排列的標籤與金額會爭奪寬度;畫面底部的浮動按鈕則可能蓋住最後一段說明。優先讓文字容器隨內容增長,必要時將水平排列的資訊改為垂直排列,並在可捲動內容底部預留空間。不要靠縮小文字來掩蓋大字級下的故障。
遇到「測試偶爾通過」時,先確認測試是否一直使用相同 UDID、App 是否在切換級別後重新啟動,以及斷言是否誤選畫面外的同名元素。確認條件穩定後再修改版面,避免把裝置狀態造成的干擾誤判為程式碼回歸問題。
整理成可維護的檢查清單
把裝置、執行階段和支援的文字級別放進測試工作設定,逐級執行同一套介面測試。每次失敗都保留級別、斷言位置與截圖;每次修復後,至少重新測試出錯級別及其相鄰級別。對於缺乏可靠自動判準的裁切與重疊,安排截圖複核,不要把「元素存在」當成可以上線的結論。
最後手動走一遍最重要的使用者路徑:放大文字後讀完說明、找到主要按鈕、完成操作並返回。測試的目標不是讓所有字級產生相同的截圖,而是確保每個支援的字級下,內容仍能讀完,操作仍能完成。
常見問題
只測最大的文字級距就夠了嗎?
不夠。至少測預設、較大及產品支援的最大級距;中間級距也可能因換行位置不同而發生遮擋。
測試找得到元素就代表版面正常嗎?
不代表。還須確認重要控制項可以點擊、內容可以捲動到,並檢視失敗截圖;存在性檢查無法找出所有截斷。
把下一次建置交給專屬雲端 Mac。
確認 ViewMini 的機型、地區與租期,再設定符合工作流程的獨享實體節點。