UI測試是AI需要的護欄:clipboardwire的故事
作者因Wayland下剪貼板同步問題,用AI(Claude Code)將Java項目ClipCascade重寫為Rust,創建了輕量級二進制工具clipboardwire。過程中發現AI開發的關鍵瓶頸是反饋質量而非編碼能力,而UI測試是讓AI可靠迭代的護欄。
文章情報
要點
- AI生成代碼時,缺乏測試會導致修復舊bug產生新bug,陷入循環。
- 投入時間編寫涵蓋UI的測試套件後,AI的迭代速度和可靠性顯著提升。
- 作者作為人類的主要貢獻是方向決策(簡化認證、威脅模型、優先支持Wayland),而非編碼。
- 項目clipboardwire以單二進制、數MB內存運行,替代了原來需要500MB堆的Java方案。
為甚麼重要
這條新聞值得關注,因為AI生成代碼時,缺乏測試會導致修復舊bug產生新bug,陷入循環。
技術影響
可能影響模型選型、推理成本、產品能力和評測基準。
從去年12月起,作者一直忍受着日常工作中的小煩惱:他同時使用兩台機器——運行Wayland的Ubuntu筆記本和一台Windows PC。通過Deskflow(Synergy的免費延續版)從Linux控制Windows,鍵盤鼠標同步完美,但剪貼板不同步。而Deskflow在X11下可以同步剪貼板,卻與Wayland不兼容。
他嘗試了KDE Connect等替代方案,但都不穩定,有時能用,有時需要重啓或重新配對。對於需要始終可用的工具,這種不一致性比沒有更糟。於是他不得不通過Google Chat給自己發送剪貼板內容,繁瑣且低效。
在論壇上,他發現了一個有前景的方案:ClipCascade。它有Linux和Windows客户端,通過中央中心轉發消息。然而,它基於Spring Boot的Java應用,推薦的最小堆內存是512MB。為了同步幾行文本,在本地網絡上運行這樣一個龐然大物,作者無法接受。他關閉了瀏覽器,打開了Claude Code。
“讓我們用Rust重寫它”
作者從未認真寫過Rust,只讀過一兩章相關書籍。他選擇Rust是因為兩個硬性要求:單一二進制、無運行時加載,以及內存安全。如果一個進程要在網絡中監聽端口,他寧願任何錯誤以panic結束,而不是緩衝區溢出。他還明確從一開始就優先支持Wayland。
與Claude Code合作有一個獨特的節奏:他給出高級指令,然後讓AI運行,自己去做其他工作。一段時間後回來審查diff,指出下一步方向,再次讓AI繼續。幾天後,一個可用的工具誕生了:兩個客户端、一箇中心、WebSocket消息、基礎認證。
然而,bug開始出現。每次修復一個bug,另一個可能又回來,或者出現新問題。因為沒有持久記憶,AI不記得之前修過同樣的問題。幾天後,作者意識到問題不在於AI,而在於沒有測試來驗證修復是否破壞了其他功能。這是一個帶圖形UI和異步行為的系統托盤應用,手動測試困難且容易遺漏。
於是作者花了一整天時間,要求AI生成一套涵蓋圖形UI的測試套件。他堅持要實現:每次push運行的第一層冒煙測試、通過DBus驅動Linux托盤菜單測試、使用UI Automation API的Windows托盤圖標測試、用egui_kittest的設置對話框UI測試,以及檢查單例鎖的集成測試。CI在每次push時都在Linux和Windows上運行所有測試。
有了測試之後,一切發生了改變。AI變得更加可靠,因為每當它破壞某項功能,我們能立即發現;修復時也能確認真的修好了。作者認為這是整個項目中最可複用的教訓:測試不是“你應該做”的負擔,而是AI代理需要的護欄,使其不會偏離軌道。
在項目過程中,作者自己做出了一些關鍵決策:
- 簡化認證:ClipCascade有複雜的認證方案,作者將其簡化為基於TLS的HTTP Basic認證,因為運行在自己的LAN和VPN中,不需要PBKDF2或密鑰派生輪數。
- 誠實威脅模型:中心在TLS終止後能看到明文剪貼板,沒有客户端間端到端加密。這是故意為之,因為機器在自己控制下;如果信任自己的機器(存有SSH密鑰、Cookie等),添加E2EE只是安全劇場。
- 單二進制三種模式:同一個可執行文件可作為客户端(connect)、中心(serve)或兩者同時運行(host),方便打包和部署。
- 系統托盤而非守護進程:托盤圖標顯示實時狀態(連接中/已連接/斷開連接),讓用户粘貼前即可看到狀態,而非失敗後才察覺。
關於Wayland,作者特別指出,一旦明確要求優先支持,GTK + libayatana-appindicator的實現在第一次嘗試就成功,沒有怪異的hack或X11回退。這也許在2026年已不令人驚訝,但正是Deskflow不支持Wayland促成了整個項目。
作者總結了三個意想不到的體會:
- 瓶頸是AI接收反饋的質量,而非其編碼能力。在手動診斷bug時,速度為零;一旦有測試給出明確的“通過/失敗”信號,速度倍增。
- 作者真正的貢獻在於方向,而非編程。最重要的決策——簡化認證、優先Wayland、定義威脅模型、推動UI測試——都是產品和架構決策,而不是代碼。
- “不懂Rust”在幾小時內就不再是障礙。不是因為他學會了Rust(他仍不傳統地懂Rust),而是因為他能夠通過閲讀diff、理解整體結構來指導項目,讓AI處理慣用細節。這既令人解放也令人失落。
項目名為clipboardwire,託管在github.com/davefx/clipboardwire,每個發佈版有.deb、.rpm和.msi包。macOS版本即將到來。作者每天在Linux和Windows之間使用,服務器僅佔用數MB內存,而Ctrl+C終於不再需要經過Google Chat。