
說來掩面。上班當 PM 的時候,我都記得要幫開發同事排單元測試跟 SIT 的時間,自己做的時候卻把這段忘得一乾二淨,想說在我手機上都跑得動了,有什麼不夠的嗎?
直到上線前,我想說一直叫 Claude Code 寫,如果有什麼漏洞我沒那個本事注意到,還是請個第三方檢查一下好了。
Vibe Coder 的第三方還是 AI。那天晚上我先自己去問了 ChatGPT 的 Codex,隔天早上才請 CC 寫一份派工指令,順便交代了第二件事:建立測試工作流。
我不會寫測試,也不知道該測什麼,那份簡報是 CC 寫好讓我貼過去的。我後來才發現那份簡報裡已經把該測哪幾塊指定好了:計分、人物濾鏡、章節時間分組、PDF 分頁數、評語的回應解析、日期區間。這就是之後的測試骨架。
Codex 交回來的東西超出我預期。它不只寫了八條測試,還先改了幾個檔案的結構。原來我的程式碼本來測不了,得先把規則從畫面裡抽出來,變成可以單獨呼叫的函式。那天的 commit 寫著「測試接縫抽取+八條純邏輯單元測試(全數通過)」。
然後我拿去問 CC,它回答「它的測試我全收,它的優化建議我砍了一半」。
我想說CC你收個頭啦,是不會自己先想到嗎。
不過它也沒閒著,看完八條之後自己又補了五條(計分跟人物濾鏡),所以開工後第六天,測試從零變成十三條。
一個半月後,《這趟》有 50 條測試,四個 App 加起來 118 條(這隻 32、這餐 25、這場 11),全部是純邏輯測試。
看 commit 紀錄,來源只有三種。
跟著新功能生:自動偵測旅行、特輯章節、雙尺度給分、攝影建議改版、早安圖產生器,每批新規則自帶測試。
跟著回饋生:
跟著修 bug 生:審查修正批、送審前的審查修正批,修完把案例鎖進測試。
我本來以為 AI 會根據功能憑空想像一批測試案例。結果比我想像的更好:我抱怨過的每件事,幾乎都變成一條測試。
還有一種測試不是為了抓新錯,是為了確認舊的還在。這件事在公司叫回歸測試,我以前只在排程表上看到這個詞,這次才知道它長什麼樣子。
以《這趟》為例,從旅程偵測、日期時區,到故事書的章節切分與人物濾鏡,最後是分數計算與大模型的回應解析。
| 測的東西 | 例子 |
|---|---|
| 旅程偵測 | 連續在外算一趟、中間沒拍照要接起來、超過三天要切開、太短或太少張不算 |
| 日期時區 | 結束日用隔天凌晨、日光節約時間邊界 |
| 章節切分 | 時間間隔剛好在邊界要不要分章、第 41 張要不要另起一段 |
| 人物濾鏡 | 全留、全去、只留旅伴三種模式的邊界 |
| 分數計算 | 分數各部分照不照校準後的公式、會不會超出公布範圍 |
| 大模型回應解析 | 把模型回的編號、項目符號、開場白剝掉;回太短要拒絕 |
這些都是我最不想看到改 A 壞 B 的東西。
有天我自己發現一個問題:評語張冠李戴。
有一張是甜點和小物,評語卻寫「建築與標示的交錯,帶給人歷史感」。再往下一張根本是菜單,被說成「建築與木造相呼應」。連我在博物館拍的照片也被誤解。
原因讓我印象深刻:AI評語不是「看」照片寫的。 裝置端的語言模型收到的是掃描訊號組成的一行字,主題、標籤、時段、分數,照片標籤一誤判,句子就會一本正經地胡說。
修法有兩段:文件、菜單、標示這類標籤的照片不進點評名單;標籤信心不足的照片,評語降級成保守句,只講時段和分數,不指名照片裡有什麼。寧可平淡,不可瞎掰。
瞎掰一次,使用者對所有評語的信任就打折。
有意思的是,前面每次修完 bug 都會補一條測試進去,這次沒有。改完到今天,「評語會不會張冠李戴」這件事一條測試都沒有。
不是忘了,是寫不出來。單元測試的寫法是「我預期答案是 X,跑出來不是 X 就報錯」,那個「我預期」在程式裡叫 assert。分數算錯我寫得出 assert,章節該不該切我也寫得出來。但「這張甜點的評語好不好」,我寫不出來。
要驗這種東西得換一套方法,而且要自己出考卷。那是另一個題目,留到回顧那篇再講。
整理這篇的時候,我隨口問了 CC:我上班的時候會讓開發同事做好幾種測試,我們現在的測試都完整了嗎?有什麼該補的?
它馬上洋洋灑灑列了四類我沒有的:
整合那一層我其實是用人工補的:裝到真機走一遍,加上朋友試用。還有一個習慣,是這次整理才發現它有名字。調參數的時候一律跑金澤那批 762 張,同一批照片才比得出這次是變好還是變壞。
十分感謝這次的整理。我們又討論了一輪對個人開發者 CP 值最高的幾項,通通放進開發那條對話串的待辦事項裡了。
這個系列同步寫在我的部落格:yojuhsu.com/blog
前一篇:【Day14】比新手前進一點點
下一篇:【Day16】功能都有了,我卻不想打開第二次