App Debug Acceptance 是編譯進 Debug App 的驗收入口。Agent 在獨立 Swift 檔案中準備場景、呼叫正式程式並寫斷言;App 完成初始化後,依啟動參數執行指定 case,將結果寫入同一輪 run ID 的 Log。
appDebugCode 是我在 2023 年留下的掛點,用來在 App 初始化完成後快速重跑指定 function,驗證修改。當時 SwiftUI Preview 在我的專案裡不夠好用,部分功能也依賴 App 完成初始化,因此需要一個能在完整 App 環境中直接執行程式的位置。
後來我也整理過供 Agent 操作 App 的 Automation,但 Agent 仍常採用「截圖 → 判斷畫面 → 傳送遙控按鍵 → 再截圖」的流程。每輪驗收都要重新導航、準備設定,並從畫面確認操作進度;修復後還要重走一次。播放器 seek 的驗收也顯示,Agent 已經知道怎麼執行 seek。
這次改造把 Agent 的驗收工作單位固定為獨立 Swift case,並寫入 Skill 的執行流程:由程式準備資料與設定、呼叫正式方法、等待完成訊號並作斷言。修復後可以選擇同一個 case、帶入相同輸入重跑,再以新的 run ID 核對結果。原有掛點得以保留,個別任務則不必再共同修改 appDebugCode。
| 驗收環節 | 以前:逐步截圖與遙控 | 現在:Swift case |
|---|---|---|
| 準備場景 | 透過 UI 依序切換設定、選擇來源、搜尋與進入影片;每輪重新導航到目標狀態。 | 由 case 寫入本次資料與設定,帶入指定輸入,再呼叫正式搜尋或播放流程。 |
| 執行動作 | 每一步都經過截圖、判斷畫面和焦點、傳送按鍵,再查看下一張截圖。 | 在同一段 Swift 程式中串接正式方法呼叫與非同步等待,動作之間不需要逐步交回 Agent 看圖決定。 |
| 判定結果 | 從畫面確認是否進到下一步;精確的播放器位置或內部狀態還要另外查證。 | 直接讀取實際狀態作斷言,例如 seek 後的位置、暫停狀態與播放時間是否前進,並記錄檢查名稱和結果。 |
| 修復後重跑 | 重新操作同一串選單與按鍵,再確認測試設定和畫面位置。 | 沿用同一個 case 與輸入,以新的 run ID 重跑,對照每項檢查。已編譯的 case 可直接重新啟動;改過 Swift 程式則重新建置與安裝。 |
以目前的 HTTPPlayback case 為例,驗證「暫停時 seek」會執行以下檢查:
PlayerHelper 開片並保持暫停,等待播放器可 seek。AVPlayer 時間,等待 500 毫秒後再次讀取,斷言時間變化小於 0.1 秒,確認暫停狀態確實保留。這段測試一次由 case 執行,失敗時可從檢查名稱區分「位置不對」與「暫停沒有保留」。修復後直接重跑相同條件;焦點、字幕和排版等畫面問題,再以實際畫面驗收。
入口放在 App 原有初始化流程之後:
#if DEBUG
await appDebugCode()
#endif
執行順序如下:
flowchart LR
A["App 初始化"] --> B["appDebugCode"]
B --> C["依 case ID 分派"]
C --> D["case.run(runID:)"]
D --> E["正式流程與斷言"]
appDebugCode 將啟動參數交給 StudyTVAcceptanceRuntime.runRequested,由它處理 case 查找與開始/完成事件。各 case 自己準備設定和測試資料,呼叫本次要驗證的正式功能。
Xcode 工具負責建置;主機端 helper 負責裝置確認、部署、啟動與取回證據。業務斷言留在 App 的 case 裡。