Communitygithub.com

beraki/my-code-factory-skills

記錄 UI 行為測試過程的視覺證據,代理程式透過電腦操作進行實際測試,螢幕錄影會包含結構化測試/斷言註解,最後將影片和結果摘要發佈到 PR 和追蹤問題。

my-code-factory-skills 是什麼?

這是一個名為「證據驅動測試」的 AI 代理技能,其核心目的是在開發流程中提供可驗證的行為證據,取代僅靠文字描述的主張。它通過錄製代理程式在實際應用程式上進行電腦操作的過程,並在錄影中嵌入結構化測試註解(如 setup、test_start、assertion),生成帶有時間戳的 annotated 影片,以及一份包含測試結果、環境資訊和確切提交版本的報告。該技能支援多種平台(Linux、macOS、Windows)和螢幕錄製方案,並能自動選擇合適的擷取來源(如 x11、wayland、avfoundation、gdigrab),同時提供 crash-safe 的原始錄製保護機制。對於沒有 GUI 的環境,它提供 headless 路徑,透過 Playwright 錄影或腳本截圖來維持相同的斷言紀律;對於有 GUI 但代理缺乏內建電腦操作工具的情況,則可整合 cua-driver 作為執行器。錄製完成後,技能會自動將影片和報告上傳至 PR 評論和追蹤問題,確保每次變更都有具體的視覺證據。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beraki/my-code-factory-skills/tree/HEAD/evidence-driven-testing

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

證據驅動測試

記錄帶有註解的行為證明,然後將其附加到 PR 和追蹤問題。

錄影是你透過電腦操作測試應用程式的過程:啟動錄影器,然後親自操作應用程式 — 點擊、輸入、導航 — 逐一執行每個測試目標。影片中的每一個動作都是即時執行的測試;除非影片顯示了該互動過程,否則它作為證據毫無價值。如果工具鏈沒有電腦操作工具,但存在 GUI,請改用 cua-driver 來操作(見下文)— 這仍然是你的即時操作過程。

配套的錄影器 scripts/evidence.py 使用 FFmpeg 在 Linux、macOS 和 Windows 上擷取顯示畫面,為你在測試時添加的每個註解加上時間戳,在停止時將它們燒錄到影片中,並使用 ffprobe 驗證結果。它會在 session 資料夾中寫入 evidence.mp4、report.md 和 manifest.json。

輸入

  • 測試目標(必填):要驗證的行為/流程,以可測試的陳述句表達。
  • PR / issue(可選):張貼證據的位置。如果省略,則僅傳送給請求者。

錄影器

下面的 EVIDENCE 代表此技能資料夾內 scripts/evidence.py 的路徑(無論技能安裝在哪裡,例如 ~/.claude/skills/evidence-driven-testing/scripts/evidence.py)。它只需要 Python 3 和 FFmpeg。

  • 先檢查: python3 $EVIDENCE doctor — 驗證 ffmpeg、ffprobe、libx264 和 ass 濾鏡(ready),然後確認哪個螢幕擷取來源在此機器上可用(capture_ready 並且來源 auto 會自動選擇)。僅在工具鏈缺失時才以非零值退出;在錄製之前請先閱讀 capture_ready。

  • 平台(--source auto 選擇第一個可用的):

    作業系統來源需求
    Linux X11 / XWaylandx11 (x11grab)已設定 DISPLAY
    Linux Waylandwayland (wf-recorder)已設定 WAYLAND_DISPLAY,wf-recorder 在 PATH 中,並且已確認合成器支援 wlr-screencopy — 可以是已知的 wlroots 合成器(Sway、Hyprland、river、Wayfire、labwc、dwl、niri)或透過 wayland-info 驗證。GNOME 和 KDE Wayland 無法以此方式擷取;doctor 會告知。對於 X11 應用程式請透過 XWayland 使用 x11,或使用備用錄影器。--source wayland 仍會強制使用它
    macOSavfoundation已授予終端機 / 代理主機應用程式螢幕錄製權限;doctor 會列出 --screen-index 可用的螢幕索引
    Windowsgdigrab任何標準的 ffmpeg 建置;使用 powershell 進行行程檢查

    預設為全螢幕擷取;--geometry WxH 和 --offset X,Y 可在 x11、wayland 和 gdigrab 上裁剪區域。XWayland 只能看到 X11 視窗,因此當被測應用程式是 Wayland 原生時,請優先使用 wayland 來源。

  • 崩潰安全原始錄製:原始錄製是 MPEG-TS(raw.ts),因此如果錄影器被強制終止或崩潰,已擷取的內容仍然可以探查和渲染。stop 會將其重新混合或重新編碼為標準的 evidence.mp4。

  • 停止方式:在 Linux 上,透過 pidfd 向錄影器發送訊號。在 macOS 和 Windows 上,start 會啟動一個小型監督行程,該行程擁有 ffmpeg 子行程,而 stop 則要求它(透過 session 資料夾中的 stop.request)中斷、終止,然後殺死;完成後會寫入 recorder-exit.json。永遠不會向裸 PID 發送訊號,因此不會影響到被回收的 PID。如果監督行程在錄影器仍在運行時死亡,stop 會拒絕並告訴你需要手動停止哪個 PID。如果它在記錄已啟動的行程之前就死亡,stop 會保持阻塞狀態,直到你親自檢查是否有殘留的錄影器,然後使用 --accept-untracked-recorder 重新運行它;報告隨後會包含該注意事項。

  • 備用錄影器:當 doctor 報告沒有擷取來源時(例如沒有 wf-recorder 的 Wayland):cua-driver recording start <dir> / stop(請參閱 cua-driver 部分),或使用作業系統的錄影器(macOS:screencapture -v out.mov)。在這些路徑上沒有註解疊加層,因此請將註解協議保留為檔案 — 一個 assertions.md,列出每個 setup / test_start / assertion 及其結果和近似影片時間戳,與 headless 路徑完全相同。

  • 永遠不要將 --source test(合成圖案產生器)作為 UI 證據呈現。它僅用於對工具鏈進行冒煙測試;儲存庫中的 tests/test_evidence.py 會使用它。

操作說明

1. 準備螢幕

  • 最大化瀏覽器/應用程式視窗;關閉彈出視窗、通知和額外面板。
  • 在錄製之前導航到起始狀態(已登入、正確的頁面),除非設定本身是待測項目。
  • 記錄正在測試的確切修訂版本:git rev-parse HEAD 和 git branch --show-current(或部署 URL)— 錄影器會將它們蓋印到報告中。

2. 開始錄製

  • 在第一個有意義的動作之前開始螢幕錄製:

    python3 $EVIDENCE start \
      --output .artifacts/<task-name> \
      --title "<正在驗證的內容>" \
      --commit "$(git rev-parse HEAD)" --branch "$(git branch --show-current)" \
      --environment "<作業系統 / 瀏覽器 / 顯示 / 部署>"
    

    它會列印一個包含 session 路徑和所選 source 的 JSON;請保留該路徑(SESSION=...)以供後續所有命令使用。來源會自動偵測並擷取整個螢幕;僅在 doctor 或情況要求時才傳遞 --source、--geometry、--offset、--display/--xauthority (X11)、--screen-index (macOS) 或 --output-name (Wayland)。

  • 添加一個描述起始上下文的 setup 註解:

    python3 $EVIDENCE annotate "$SESSION" --type setup \
      --message "已登入,正在導航到連接器頁面"
    

3. 透過電腦操作進行測試,邊測試邊註解

  • 透過在即時應用程式上進行電腦操作來執行每個互動 — 錄影會捕捉你的操作過程,因此測試和證據是同一行為。以可觀看的速度操作:在每個動作後讓 UI 穩定下來,以便狀態變更在影片中可見。

  • 在每個命名的測試開始時,以 Jest 風格添加一個 test_start 註解:

    python3 $EVIDENCE annotate "$SESSION" --type test_start \
      --message "當權限為 'always' 時,它應直接執行工具"
    
  • 在每次檢查之後,添加一個帶有 --result passed、failed 或 untested 的 assertion 註解:

    python3 $EVIDENCE annotate "$SESSION" --type assertion --result passed \
      --message "工具在沒有權限提示的情況下運行"
    
  • 斷言規則:

    • 每個有意義的狀態變更對應一個斷言 — 合併,不要為每個 UI 標籤都添加註解。
    • 使用 "Precondition: ..." 斷言來建立起始狀態。
    • 保持在 80 個字元以內,高信號(錄影器會拒絕更長的消息)。
    • 如果測試無法運行(缺少先決條件、授權視窗已過期),將其標記為 untested 並說明原因 — 永遠不要跳過而不記錄。
    • 時間戳記錄的是你斷言的時間,而不是它是否為真 — 在選擇 passed 之前請先查看螢幕。

4. 停止並審查

  • 在最後一個斷言之後停止錄製:

    python3 $EVIDENCE stop "$SESSION"
    

    這會停止擷取(優雅地,以便錄影器刷新;只有在忽略請求時才會升級),將註解燒錄到 evidence.mp4 中,探查結果,並在旁邊寫入 report.md 和 manifest.json。成功時會列印 "verified": true;如果渲染失敗,session 會被標記為 finalization_failed — 修正報告的原因並再次運行 stop(重試不會向錄影器發送兩次訊號)。如果無法再安全地向錄影行程發送訊號(它已死亡,或其 PID 現在屬於另一個行程),session 會被標記為 recorder_lost。再次運行 stop 會完成任何已擷取的影片,但僅在確認該錄影行程已消失後 — 如果它仍在運行,請先停止它,否則影片可能會在仍在寫入時被渲染。

  • 在分享之前確認錄影捕捉到了關鍵時刻:在每個斷言時間戳處提取一個影格(ffmpeg -ss <t> -i evidence.mp4 -frames:v 1 frame.png)並檢查狀態和標籤是否可見。

  • 填寫 report.md 的「注意事項」(Caveats) 部分;永遠不要留下佔位符。

5. 張貼證據

  • report.md 就是報告:測試了什麼、環境 + 確切提交、每個測試的通過/失敗、注意事項。請對其進行擴展,而不是從頭重寫。
  • 將影片 + 摘要作為 PR 評論張貼(如果是你的 PR,則嵌入到 PR 描述中)。gh pr comment 無法附加本地影片 — 請在已認證的瀏覽器中透過 PR 的評論框上傳 evidence.mp4,或將其上傳到主機並連結(例如 before-and-after 上傳適配器)。重新開啟評論並確認影片可以播放,然後再聲稱已張貼。
  • 將相同的影片附加到追蹤問題(Linear/Jira),並附上一行結果。
  • 將報告 + 錄影發送給請求者。

防護措施

  • 影片必須顯示實際的測試操作過程。切勿將腳本播放、拼接剪輯或合成素材作為錄影呈現;如果工具鏈缺乏電腦操作工具但存在 GUI,請透過 cua-driver 操作;完全沒有 GUI 時,請改用 headless 路徑。
  • 切勿錄製半遮蓋或並排的視窗 — 請先最大化。
  • 切勿錄製顯示機密、令牌、客戶資料或付款詳細資訊的螢幕;如果某個流程需要它們,請將其標記為 untested 並說明原因。
  • 在驗證修復時,請連同新的成功一起顯示或參考舊的失敗。
  • 始終說明測試時的精確提交/分支/部署。

沒有電腦操作工具?使用 cua-driver 操作(有 GUI)

當存在顯示器但代理沒有內建的電腦操作能力時,請使用 cua-driver(macOS / Windows / Linux)作為執行器。這仍然是你即時測試應用程式 — 錄製規則保持不變;僅輸入機制不同。

  • 在錄製之前使用 cua-driver doctor 驗證設定。如果安裝了 cua-driver 技能,請閱讀它並遵循其協議 — 操作前快照(snapshot-before-action)的不變性是強制性的。
  • 每個互動輪迴:launch_app → get_window_state(無障礙樹 + 螢幕截圖)→ 透過 element_token 操作(click、type_text、press_key)→ verify_state 驗證預期的後置條件。每個 verify_state 檢查都對應一個 assertion 註解。
  • 只要 doctor 報告 capture_ready: yes,就繼續使用上述配套的錄影器進行影片和註解;cua-driver 僅提供輸入。
  • 否則,cua-driver recording start <output-dir> / cua-driver recording stop 就是錄影器(需要輸出目錄,且守護行程必須正在運行:cua-driver serve)。影片擷取預設為啟用,並在停止時完成到 <output-dir>/recording.mp4 — 但在 Windows/Linux 上,它會 shell 呼叫 ffmpeg,因此缺少 ffmpeg 或顯示器只會產生每輪的軌跡資料夾(前/後螢幕截圖、action.json、click.png),不會有影片。停止後,在引用 recording.mp4 之前,請先確認它是否存在;如果不存在,請修復錄影器,或根據 headless 協議將每輪的前/後螢幕截圖呈現為編號的擷取。
  • 如果在此路徑上沒有可用的註解疊加層,請將協議保留為檔案:一個 assertions.md,列出每個 test_start / assertion 及其結果,與 headless 路徑完全相同。

Headless 路徑(無 GUI)

當代理沒有桌面可錄製時,保持相同的斷言紀律;將錄影器替換為腳本式擷取:

  • 將所有內容儲存到 .artifacts/<task-name>/(將其加入 .gitignore — 證據會被上傳,永遠不會提交)。將擷取腳本與擷取的內容放在一起,以便運行是可重現的。

  • 螢幕截圖:before-and-after CLI(@vercel/before-and-after)會擷取 URL 或元素,其配對可以直接饋送給 PR 嵌入。在容器/虛擬機器中,如果 Chrome 失敗並顯示 "No usable sandbox",請設定 AGENT_BROWSER_ARGS="--no-sandbox"。

  • 影片 / 多步驟流程:一個一次性的 Playwright 腳本,無需將 playwright 添加到專案的依賴項即可運行:

    npx --yes --package=playwright node record.mjs
    

    (單純使用 npx playwright node record.mjs 會失敗 — node 不是 Playwright CLI 命令;--package=playwright 才是將模組放到路徑上的方法。)最小化的 record.mjs:

    import { chromium } from "playwright";
    const browser = await chromium.launch();
    const context = await browser.newContext({
      recordVideo: { dir: ".artifacts/<task-name>/" },
    });
    const page = await context.newPage();
    await page.goto("http://localhost:3000/path-under-test");
    // ...驅動流程,每個步驟一個有意義的狀態變更...
    await context.close(); // 完成 .webm
    await browser.close();
    

    如果檔案很大,可以使用 ffmpeg 修剪或壓縮。

  • 註解協議變成檔案:按測試順序對擷取內容進行編號,並在名稱中包含斷言 — 01-precondition-signed-in.png、02-it-saves-on-blur-passed.png — 並在 artifacts 資料夾中保留一個 assertions.md,列出每個 test_start / assertion 及其結果(passed / failed / untested + 原因)。

非 UI 變更仍需要證據

  • API / 效能:一個帶有測量數字的腳本探查 — 每個階段的請求計數、前/後延遲 — 擷取到 probe-output.txt。
  • 渲染 / Canvas / 著色器:渲染的影格加上像素斷言(差異值),由人工檢查並儲存為 PNG。
  • 代理行為:顯示工具呼叫和回應的相關對話記錄摘錄。
  • 錯誤修復:在撰寫修復程式碼之前重現並擷取失敗 — 該擷取是前/後配對中的「前」半部分。

擷取衛生

  • 確認你正在探查的伺服器正在運行你的程式碼(正確的埠、正確的行程),特別是在多個代理共享一台機器時:lsof -i :<port> — 或者如果未安裝 lsof,請使用 ss -ltnp "sport = :<port>"。
  • 在錄製之前,關閉可能改變應用程式狀態的其他工具(如除錯工具)。
  • 如果一個測試步驟需要等待非同步操作(例如 API 呼叫),請在繼續之前確認操作已完成(透過 UI 狀態或網路日誌),而不是猜測時間。
  • 對於 headless 擷取,確認檔案已完全寫入磁碟後再將其上傳或引用爲完成。

常見問題

問題解決方案
doctor 說 ffmpeg 缺失在 macOS 上透過 brew install ffmpeg、在 Ubuntu/Debian 上透過 sudo apt install ffmpeg、在 Windows 上透過 choco install ffmpeg 安裝,或從 ffmpeg.org 下載。確保它在 PATH 中。
doctor 說 capture_ready: no檢查 --source 參數是否與你的顯示伺服器相符(Linux 上的 X11 與 Wayland)。在 macOS 上,授予終端機螢幕錄製權限(系統設定 → 隱私與安全性 → 螢幕錄製)。在 Wayland 上,安裝 wf-recorder。
stop 報告 finalization_failed檢查 raw.ts 檔案;如果為空,可能是錄影器從未啟動。如果非空,則可能是 ffprobe 失敗 — 手動運行 ffprobe raw.ts 以查看錯誤。
註解未燒錄確認你使用了正確的 SESSION 路徑,並且 annotate 命令在 stop 之前運行。檢查 manifest.json 中的註解計數。
gh pr comment 說影片太大使用 ffmpeg -i evidence.mp4 -vf "scale=iw/2:ih/2" compressed.mp4 壓縮,或上傳到外部主機並連結。
Playwright 無法啟動 Chrome/chromium設定 AGENT_BROWSER_ARGS="--no-sandbox" 並檢查 npx playwright install chromium。

相關技能