iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Vibe Coding

AI 寫不好,可能是我沒說清楚:30 天打造 ClarifyBuild,讓 Vibe Coding 從需求開始系列 第 21 篇

Day 21|browser test 補完了,我先沒補下一條,而是把測試工具抽出來

  • 分享至 

  • xImage
  •  

Day 20 結尾我留了一句:

Day 21 如果還要加 browser test,我會先把今天的 browser harness 抽乾淨,再補 case。

今天就是在兌現這句。

Day 20 終於補了 browser test。

不是很大的 end-to-end,只是針對 Day 19 的 draft import confirmation,也就是「選了檔案,要先確認才會取代目前 draft」這條規則,補了三條使用者真的看得到的路徑:

  • 壞檔不跳確認,而且目前 Prompt 還在
  • 好檔按 Cancel,目前 Spec / Prompt 都還在
  • 好檔按 Confirm,回到 Specify,重新產生 imported draft 的 Spec

這三條測試會真的打開 index.html、載入 src/main.js、用 headless Chrome 跑,也會處理 native window.confirm()。

我其實很想直接補下一條。

例如從 Idea Entry 一路走到 Prompt Preview。

但先停一下。

Day 20 留下來的問題不是 coverage 還不夠,而是 browser test harness 已經開始長出重量了。

這裡的 harness,指的是讓 browser test 能跑起來的那包工具:local server、Chrome 啟動、Chrome DevTools Protocol(CDP)連線、page helper、file input helper。

Day 20 的 test/browserFlow.test.js 有 522 行。裡面大約 240 行是這些工具,三個情境本身大約 90 行。

下一條測試如果繼續放同一個檔案,它會繼續長。

如果新開一個 browser test 檔案,就不能直接去 import browserFlow.test.js 裡的 helper。

因為測試檔 import 測試檔,會連對方的測試也一起載入。

最後只能把那約 240 行複製一份。

所以 Day 21 的主論點很簡單:

先降低下一次補 browser test 的摩擦。

今天不重寫測試策略、不導入 Playwright,也不改產品行為。

只是把 Day 20 那包「為了讓 browser test 跑起來」的工具,從情境測試裡抽出來。


留下情境,搬走工具

Day 20 的 test/browserFlow.test.js 裡有兩種東西。

第一種是產品情境。

例如:

browser import rejects invalid draft without confirmation and preserves current output

這種內容在講 ClarifyBuild 的產品規則:

  • 壞檔不應該跳確認
  • Cancel 不應該覆蓋目前 draft
  • Confirm 之後要回到 Specify
  • 重新產生的 Spec 要來自 imported draft

這些要留在測試檔裡。

第二種是測試工具。

這類東西不是 ClarifyBuild 的產品規則。

它們只是為了讓 browser test 能跑。

所以 Day 21 新增了 test/helpers/browserHarness.js。

搬走的是:

  • local static server
  • headless Chrome launch
  • CDP connection
  • page helpers,例如 goto()、click()、text()、value()、waitForText()
  • 暫存 draft file helper
  • file input helper,也就是透過 DOM.setFileInputFiles 選 JSON 檔

留下的是:

  • 三條 import confirmation browser 情境
  • ClarifyBuild 專用的測試資料
  • 每條情境要檢查的畫面結果

抽完之後,browserFlow.test.js 讀起來比較接近使用者流程:

載入目前 draft
產生目前輸出
選擇 imported draft file
處理 confirm / cancel
檢查畫面

但還沒有完全乾淨。

confirm 的處理仍然是原始 CDP。三條測試都直接用 Page.javascriptDialogOpening 和 Page.handleJavaScriptDialog:第二、三條幾乎一樣,第一條是另一種寫法,用來確認壞檔根本沒跳確認。

形狀還沒收斂,所以我先不抽。

這個切法不是最終答案,只是先把最明顯的工具和情境拆開。


npm test 也需要收窄

抽出 helper 後,出現一個小問題。

不帶參數的 node --test,會把名叫 test 的資料夾底下所有 .js 都當成測試檔。

所以新增 test/helpers/browserHarness.js 之後,npm test 會多跑一個 helper 檔。

它沒有測試,所以不會失敗。

但輸出會多一行:

✔ test/helpers/browserHarness.js

測試數也會從 27 變成 28。

這不是功能錯誤,但會讓人誤以為 helper 本身是一個測試案例。

所以 Day 21 把 script 從 node --test 改成:

node --test test/*.test.js

這樣 top-level 的 *.test.js 照跑,test/helpers/ 裡的 helper 照樣可以被 import,但不會被當成獨立測試檔。

代價是,之後新的測試檔如果放進子資料夾,例如 test/browser/import.test.js,npm test 不會跑它。

也就是說,接下來的測試檔要先放在 test/ 第一層,檔名以 .test.js 結尾。

這個限制目前可以接受。

如果之後真的需要整理測試資料夾結構,再一起調整 test script。


測試用資料先不抽

現在 browserFlow.test.js 裡還有一個 ClarifyBuild 專用的測試用假資料,也就是 completeMvpState()。

這個東西其實 test/appFlow.test.js 也有一份。

所以如果只看「有沒有重複」,重複已經出現了。

但我今天沒有把它抽成共用 fixture。

原因不是「完全沒有重複」。

真正原因是兩份形狀已經不一樣。

兩邊其實都要分「目前的 draft」和「匯入的 draft」。

appFlow.test.js 是叫完 completeMvpState() 再改 draft.idea。

browserFlow.test.js 則把 idea、featureName、flowLabel、behaviorTrigger 都做成參數,資料也是手寫的物件,沒有走 createFeature()、normalizeFlowRows() 這些正式程式裡的 helper。

而且這四個參數裡,目前真的被測試檢查的只有 idea 和 featureName。

所以它現在不是單純重複。

它是兩種還沒決定誰當標準的寫法。現在硬抽,只是把還沒想清楚的形狀固定下來。

這裡我比較想遵守的節奏是:

先等重複的形狀穩下來,再抽象。

Day 21 先抽 browser harness,不急著抽 ClarifyBuild fixture。


今天沒有改產品

今天沒有改 src/main.js。

沒有改 src/ui/render.js。

沒有改 src/state/appFlow.js。

也沒有碰 Day 10 到 Day 13 定下來的產品邏輯。

三條測試驗的東西沒變。

改的是測試怎麼被組織。

這件事對產品沒有直接可見的差異。

但它會影響後面幾天寫測試的成本。

如果明天要補一條從 Idea Entry 到 Prompt Preview 的 browser happy path,現在不用重新處理 Chrome 啟動和 CDP connection。

多半可以把注意力放在流程本身,頂多再補一兩個像 fill() 或 select() 的小 helper。


測試結果

Day 21 focused browser test:

node --test test/browserFlow.test.js

結果:

tests 3
pass 3
fail 0

完整測試:

npm test

結果:

tests 27
pass 27
fail 0

跟 Day 20 一樣,我跑測試的環境會限制本機網路權限。第一次跑時,本地 server 不能 bind 到 127.0.0.1;放寬權限後重跑,測試通過。


Playwright 什麼時候才換

Playwright 本來就是做 browser test 的工具。

之後換,我不意外。

Day 20 我先不用,今天整理完又看了一次:browserHarness.js 有 282 行。

其中約 240 行是 server、Chrome 和 CDP 本體,其餘是 import、常數,以及 withBrowserApp()、chooseDraftFile()、writeDraftFile() 三個入口 helper。

未來如果換 Playwright,會被它取代的主要是 Chrome 啟動、CDP 連線和那些 wait helper。

但今天卡住的不是「這些該不該自己寫」。

而是它們不該跟情境混在同一個檔案。

就算之後要換,也得先有一條邊界。

另外有兩題,換不換 Playwright 都得回答。

第一,Chrome 裝在哪裡。

我現在把 Mac 上的路徑寫死:

/Applications/Google Chrome.app/Contents/MacOS/Google Chrome

第二,CI 要怎麼拿到瀏覽器。

目前這個專案目錄裡還沒有 CI 設定,所以今天先不處理。

所以我先把「什麼時候換」寫下來。

如果出現下面幾種情況,就該重新評估 Playwright:

  • 為了下一條測試,harness 開始需要新增很多 fill()、select()、keyboard helper
  • 想看 screenshot、trace,或想知道某一步到底卡在哪裡
  • 測試要在我這台 Mac 以外的地方穩定跑

到那時候再換,要動的主要會是 browserHarness.js,加上測試裡目前還沒抽掉的 confirm 處理。

這樣換工具比較像替換一層 harness,而不是到處拆測試。


Day 21 做完後的狀態

現在測試分工變成這樣:

test/browserFlow.test.js
  放 browser-level 使用者情境

test/helpers/browserHarness.js
  放 browser test harness

這個分工只是讓下一次補 browser test 時,不用再面對同一包 Chrome / CDP / local server 工具。

Day 22 如果繼續往 browser test 走,我會補一條更完整的 happy path:進度列上的 Idea、Clarify、Scope、Specify、Spec、Prompt 六站都走過一次,中間實際流程可能還會經過 Optional Details。

不先整理的話,明天的文章很可能就會變成:

我複製了昨天那坨 CDP 工具,然後又多寫一條測試

那不是我想要的方向。

先等重複的形狀穩下來,再抽象;但當工具和情境已經混在一起時,就先拆開。

Day 21 完成。

明天見。


上一篇
Day 20|終於補 browser test,但我只測使用者看得到的事
系列文
AI 寫不好,可能是我沒說清楚:30 天打造 ClarifyBuild,讓 Vibe Coding 從需求開始 共 21 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言