iT邦幫忙

2026 iThome 鐵人賽

DAY 1
0
Software Development

Windows 桌面軟體 CI 實戰:從系統工具開發到 Zero-RDP 自動化測試錄影系列 第 1

Day 1:被遺忘在現代 CI 世界之外的 Windows 桌面應用

  • 分享至 

  • xImage
  •  

自動化驗證 win-x64

引言

如果你是一位 Web 開發者,你可能早已習慣了現代前端測試的奢華體驗:

  • 使用 PlaywrightCypress 撰寫端到端(E2E)整合測試。
  • 測試在 GitHub Actions 或 GitLab CI 上自動化執行。
  • 一旦測試失敗,CI 會自動產出 Trace Viewer、DOM 快照、以及全程操作錄影。你可以像看重播一樣,精確定位是哪一個按鈕沒有渲染出來。

然而,當場景切換到 Windows 桌面端軟體開發(不論你是用 C++、C# / WPF / WinUI 3、Rust / Tauri,還是 Python 開發系統工具),測試的世界彷彿瞬間倒退了二十年:

「本地測試一切正常,推上 GitHub Actions windows-latest 卻神秘逾時失敗。」

「打開 CI 日誌,只有一行冷冰冰的 TimeoutError: Element not found within 30.0s。」

「CI 機器在雲端,沒有螢幕可以看,更沒有 RDP 可以連進去。你根本不知道那 30 秒內畫面上到底彈出了什麼鬼東西——是 Windows 的歡迎畫面?輸入法焦點跑了?還是背景視窗把焦點偷走了?」

這就是目前無數 Windows 桌面軟體開發者與 DevOps 工程師每天都在面對的 「CI 盲測黑盒子」


真實起因:從開發「輸入法工具箱」說起

這個系列不是讀完文件寫出來的教學。它源自一個真實的開源專案——ImeModePersistence:一款解決 Windows 輸入法在視窗切換時狀態跳掉的系統級工具,目前已上架 Microsoft Store。

為了保證它在廣大用戶電腦上穩定運行,我必須在 GitHub Actions CI 上進行嚴格的自動化驗證:

  1. 真的把視窗開起來。
  2. 透過鍵盤實體掃描碼(Scan-code)模擬真實物理按鍵。
  3. 驗證中英文切換、焦點轉移、視窗縮放與關閉流程。
  4. 同時在 Windows Server x64 與 Windows 11 ARM64 執行器上通過

但在建置 CI 管道的第一週,我就撞上了無數隱形暗礁:

  • 既有的自動化工具(如 pywinautopyautogui)在面對 Windows 11 的現代應用生命週期(如 Store App 的 Shim 處理程序、XAML Island)時,較難直接進行深層走訪與非同步後置條件驗證。
  • Windows 11 現代應用導入了 XAML Island 與巢狀子 HWND 結構,UIA 的 FindFirstTreeScope_Descendants 跨不過那道邊界——同一個元素改用 RawViewWalker 手動走訪就找得到。在 ARM64 上實測三次都一致:FindFirst 約 200 ms 回報找不到,walker 4–7 ms 就拿到了。而因為探索會重試到逾時,使用者看到的是二十秒後的失敗。
  • 乾淨的 CI 映像檔第一次啟動時,會冷不防跳出「教學提示(TeachingTip)」或 OOBE 隱私條款彈窗,直接把焦點劫走。

為了徹底解決這些問題,我從 Windows 底層 Win32 API、UI Automation(UIA)COM 介面、視訊串流編碼(PyAV)到虛擬桌面隔離機制全部重做了一遍,最終催生出開源桌面整合測試框架——wintegrate


本系列的核心精神:全自動的 DevOps 思維

在自動化的 CI 上跑桌面測試,最痛苦的莫過於失敗時沒有畫面可看,只能看到一行 TimeoutError。如果每次報錯都要想辦法連 RDP 進去重現,不僅麻煩,而且那個當下的現場早就不見了。

所以設計測試流程時,最核心的考量就是 「自動把現場記錄下來」。當 CI 跑完或中途失敗時,自動在 artifacts/ 資料夾留下四樣診斷檔案:

📁 artifacts/
├── session_recording.mp4   # 1. 操作過程錄影(PyAV 串流寫入,不佔爆記憶體)
├── window_census.json      # 2. 測試前後桌面視窗清單(比對是哪個彈窗搶了焦點)
├── session_events.json     # 3. 動作事件時間軸
└── failure_screenshot.png  # 4. 失敗當下的全螢幕截圖(涵蓋所有螢幕)

有了這些產物,當 CI 上的測試在凌晨三點掛掉時,你不用手忙腳亂去開遠端連線,只要在 GitHub Actions 下載 Artifacts:

  • 打開 session_recording.mp4,用 10 秒看一眼它是在哪一步卡住。
  • 打開 window_census.json,比對一下是不是背景突然跳出了沒被關閉的系統通知。
  • 查看 session_events.json,精確確認每一筆按鍵與點擊的時序。

這四個檔案就是這個系列反覆要回答的那個問題的答案:在一台你連不進去的機器上,測試到底發生了什麼事?
自動化驗證 win-arm64


這 30 天會講什麼

適合這樣的讀者:寫 Windows 桌面應用、而且已經有(或想要有)CI 的人。 你不需要會 Python 以外的語言——雖然工具是 Python 寫的,但踩到的坑是 Win32 和 UIA 層級的,換成 C# 的 FlaUI 或 C++ 直接呼叫 UIA COM 一樣會遇到。

明天要拆的是一種不會留下錯誤訊息的失敗:你的程式碼全部執行成功,沒有任何例外,而畫面上什麼都沒發生。 那不是 bug,是你對著錯的那張桌面說話 —— 而 Windows 有三層桌面可以讓你站錯。


下一篇
Day 2:你的視窗不是你的視窗:Session、Window Station、Input Desktop 的三層蛋糕
系列文
Windows 桌面軟體 CI 實戰:從系統工具開發到 Zero-RDP 自動化測試錄影4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言