iT邦幫忙

2026 iThome 鐵人賽

DAY 3
0

同一個原因,修了 20 次

昨天說三種失敗的共同點是「都沒有訊號」。而沒有徵兆的失敗並不會自己消失。它們只是被延後,然後全部堆到某個時刻才出現。

專案來到第三個月底,那份上線準備度報告:一百多個問題、完成度 65–70%。同一天還交了兩份東西。一份測試問題回顧報告,做了完整的原因分析,分成 10 大類;一份開發檢查清單,把該注意的事項條列出來。

看起來很到位:發現問題、找出原因、修正問題、建立預防機制。

然後幾天之後,又冒出七十幾個類似的問題。


先給一個我後來才算出來的數字。那個案子裡有一類問題叫「日期元件被民國年格式遮蓋」,它在四輪測試裡出現了 20 次——不是同一張單被退回四次,是二十張不同的單,分布在不同的頁面。而它們的原因是同一個。

另一類「表單驗證沒作用」更誇張,橫跨六輪、27 張 (也就是修了 27 次)。

一開始我以為這是流程沒做好:如果第一輪就把同類一次掃完,後面十七張就不會出現。這個想法沒錯,我後面也會講那個做法。

但它不是這篇真正要講的東西。 因為它假設了一件事:那 20 次,是我們「找到」的 20 個問題。

35 張問題單,18 個 bug

我拿中期的某一輪來拆。那輪列了 35 個問題單,分布在 6 個功能:

單位資料作業:  3 個
人員資料作業:    8 個
會員資料作業:    9 個
個人資料作業:   10 個
帳號解鎖作業:    1 個
檢核項目作業:    4 個

看起來是六個功能各有各的毛病。但把標題並排看,就不是那回事了:

[A] 單位 - 必填欄位未顯示紅字
[B] 人員   - 必填欄位未顯示紅字        ← 同類
[C] 個人   - 必填欄位未顯示紅字        ← 同類

[D] 單位 - 日期元件被民國年格式遮蓋
[E] 單位 - 查詢頁日期元件無法使用     ← 同類
[F] 人員   - 日期元件被民國年格式遮蓋   ← 同類
[G] 會員   - 生日欄位沒有日期元件       ← 同類
[H] 檢核   - 日期元件無法使用           ← 同類

[I] 個人 - 修改密碼無密碼驗證
[J] 個人 - 修改密碼確認按鈕無反應       ← 同一個原因
[K] 個人 - 修改密碼長度驗證未作用       ← 同一個原因
[L] 個人 - 修改密碼不可全為數字驗證未作用 ← 同一個原因
[M] 個人 - 修改密碼一致性驗證未作用     ← 同一個原因
[N] 個人 - 未輸入新密碼驗證未作用       ← 同一個原因
[O] 個人 - 未輸入任何密碼驗證未作用     ← 同一個原因

最後那一組七個問題單,是同一個 modal 的表單提交鏈路壞掉。一個 bug,七張單。把同一個原因的併在一起之後:

原因 問題單數 真正的獨立 bug
必填欄位未顯示紅字 3 1
日期元件被民國年格式遮蓋 5 1
修改密碼驗證整組失效 7 1
必填欄位判斷邏輯錯 4 1
地址欄位與設計稿不一致 2 1
登入帳號欄位無法修改 2 1
其他(各自獨立) 12 12
合計 35 18

35 個問題單,實際上是 18 個 bug。

而這 18 個幾乎全部在前端。(因為在此刻,測試人員也僅能簡單地操作這些前端的功能)

而這個比值本身就在告訴你一件事

同一個錯誤出現在三個、五個、七個頁面,代表那些頁面是「一起被做出來的」。

而且,AI 認為這樣是對的!

我們來回顧一下這個案子的施工方法,它是大跨度:一週掃完全部頁面、十天產出全部需求文件,然後大批地產。這是 AI 最誘人的地方——它可以一次做八十幾個頁面,而你不用等。

代價是:如果那一批的理解是錯的,錯誤會被複製八十幾份。

小跨度   做一頁 → 測一頁 → 發現日期元件的問題 → 修掉 → 再做下一頁
         錯誤成本:1 個頁面

大跨度   一次做完八十幾頁 → 開始測 → 發現日期元件的問題出現在二十頁
         錯誤成本:20 個頁面,而且分四輪才被撈完

那 20 次的根源不只是「沒有人歸類」——是那 20 個地方本來就是同一批產出來的。它們不是二十次獨立的失誤,是一次失誤被複製了二十份

所以小步快跑不但沒過時,反而更重要

這件事我想特別講,因為它跟直覺相反。

AI 進來之後,「一步」可以變得非常大——大到你可以一次產出整個模組。而正因為它變得這麼便宜,很容易就跳過了「做一點、驗一點」這個動作

但敏捷講小步快跑,從來就不是因為人做不快。是因為每一步之間需要一個回饋點。

而回饋點的價值,跟步伐大小是這樣的關係:

  一步做多少 錯了要重做多少 什麼時候發現
小步 一頁 一頁 當下
大步 八十幾頁 八十幾頁 測試階段,而且分批發現

AI 把第一欄變便宜了,但它沒有把第二欄變便宜

所以那句老話在 AI 時代不但沒過時,它的權重反而更高了:

步伐可以變大,但回饋點不能變少。
而 AI 讓步伐變大的速度,遠快過我們補上回饋點的速度。

(後面講那條產線的時候,你會看到一個相反的做法:一次只做一個小單元,每一次都要跑完驗證才算數。那 43 次執行的紀錄之所以有意義,有一半就是因為它把步伐切小了。)

那為什麼同一個原因,可以撐過四輪都沒被收斂掉?

為什麼那 20 次會發生:三邊都沒有那份清單

要回答這個,得先講一件發生在第一個月的事。

客戶請了一位設計師畫了 Prototype,然後說:「這就是日後 UI 的規格。」

就是這一句,讓整件事失控。

為什麼?因為舊系統的頁面檢核條件藏在各種不同的地方——有的在事件處理裡、有的在隱藏欄位、有的在預存程序、有的在當年某個人臨時加的判斷式。我們一開始就試著用 AI 去掃描歸納,但那些東西散得太開,沒辦法一次收斂出完整的清單。再者,AI 在那個當下有一個頭重腳輕的毛病,這容日後再說。

所以合作方式當初是這樣談的:

我們        用 AI 把技術主軸建起來
客戶        提供測試案例,用它們把行為收斂出來

這個分工是合理的。舊系統的行為只有客戶知道,AI 掃不出來的部分,本來就該由他們補。

然後測試開始了,而客戶整理不出測試情境。

不是他們不配合,是那套系統跑了十幾年,沒有人說得出「這一頁應該檢查什麼」。於是每一個進來的測試人員都是憑感覺亂測,沒有一個章法

而有一件事我當時沒有想通,是後來回頭看才發現的:客戶甚至派了新進員工來測試。

那個人不知道這個系統是做什麼的。

我一開始覺得這是不夠重視。但後來想清楚了——這個安排本身,就是一個假設的證據

他們認為「測試」是一件不需要懂這個系統的事。

而這個假設不是憑空來的。在有測試案例的世界裡,它是對的:案例上寫「輸入空白,應該顯示紅字提示」,任何人都執行得了,而且新人反而更好——他不會因為熟悉而跳過步驟,也不會有先入為主。

問題是這個案子沒有案例。

沒有案例的時候,「測試」這個動作實際上要求的是另一件事:你得知道什麼叫「不對」。 而那個判斷,只存在於用過舊系統的人腦子裡。

所以派新人來測,後果是雙重的:

  有測試案例 沒有測試案例
新人能做什麼 照著執行,而且執行得很好 只能點點看
遇到怪的東西 案例說了它該長怎樣 → 判定不符 不知道那是怪的,以為本來就長這樣
產出 一份可重複的結果 一批「我覺得怪怪的」

第二列是最貴的。一個用過舊系統的人看到民國年欄位被遮住,會馬上覺得不對;而一個新人會以為它本來就長那樣。

所以這個發現機制不只是隨機——它還帶著一個系統性的盲區:所有「看起來合理但其實不對」的東西,都不會被回報。

而 Day 02 講過,那正是第二種失敗的形狀。

而這不是那個客戶特有的決定

寫到這裡我要把話講得更難聽一點,因為只怪客戶是不公平的。

資訊業本來就經常把新進人員安排去做測試。 這是行之有年的慣例,理由通常是「先熟悉系統」「門檻比較低」「不容易出事」。我自己也這樣安排過。

而這個慣例隱含的假設,跟前面那個一模一樣:測試是一件不需要太多知識的工作。

它什麼時候成立?當那份「應該檢查什麼」的清單已經存在的時候。 有了清單,測試確實是可以外包給新人的——而且外包得很好。

那什麼時候不成立?當那份清單不存在的時候。 而它最常不存在的地方,剛好是最需要它的地方:沒有人說得清楚的遺留系統。

所以真正的問題不是「派新人去測」這個動作,是我們沒有先問一句:這個專案裡,測試到底是什麼性質的工作?

如果用後面會講到的那個判準來看:

做錯了,還有沒有下游會發現?

有   →  這是工站,可以交給任何人,也可以交給機器
沒有 →  這是閘門,只有懂這個系統的人做得了

在那個案子裡,測試是唯一的發現機制——它下游沒有任何東西。照這個判準,它是閘門。

而我們把它當工站配置了。

把閘門的位置,用工站的方式配置——這件事的代價不會當場出現,它會變成四輪重複的問題單。

順帶說一件我覺得很值得想的事:AI 在這件事上的處境,跟那個新人是一樣的。

它同樣沒有那套「這個系統為什麼長成這樣」的知識,同樣只能照著它拿到的東西做,同樣會把不對的東西當成本來就長那樣。差別只在它快很多。

所以這一整個系列在處理的,其實不是一個「AI 的問題」——是一個「當執行者沒有那套知識時,你要怎麼辦」的問題。AI 只是讓這個老問題以每秒一次的速度發生。

把三邊放在一起看,會發現那份「該檢查什麼」的清單,是三邊都拿不出來的:

  有沒有那份清單 為什麼沒有
舊系統 有,但散在程式碼裡 掃描歸納不出完整的
那份 Prototype 沒有 它只表達得出畫面,不表達「該檢查什麼」
客戶 沒有 跑了十幾年,知道的人早就不在

三邊都沒有,於是測試變成了唯一的發現機制。

而它是一個隨機的發現機制。

所以那 20 次不是「修了 20 次」,是「碰到了 4 次」

現在回頭看那 20 張單的分布,意思完全不一樣:

第 1 輪   某個人隨機點到三個頁面的日期欄位   →   3 張單
第 2 輪   換一個人,隨機點到另外六個頁面     →   6 張單
第 3 輪   又換一個人                        →   7 張單
第 4 輪   ...                              →   4 張單

每一輪測到的都是同一個原因,只是換了頁面。

我原本把這件事讀成「我們修了 20 次都沒學乖」。但正確的讀法是:

那不是 20 次失敗,是 4 次隨機取樣,各自撈到了一部分。

沒有人手上有那份清單,所以也沒有人能說「這一類我們修過了,該一次掃完」。每一輪都是重新開始,因為每一輪本來就沒有連續性可言——它們不是同一個計畫的四個步驟,是四次獨立的碰運氣。

那二十次的本質因此不是「修得不夠聰明」:

沒有人能定義「對」長什麼樣,於是只能靠碰運氣去發現「錯」。
而碰運氣,是可以重複碰到同一個地方的。

https://ithelp.ithome.com.tw/upload/images/20260901/20178262yZljTBo2t8.png

而真正該害怕的,是沒有被碰到的那些

如果四輪隨機取樣撈到了二十個,那有一個問題必須問:

那些沒有被碰到的頁面呢?

那個案子有八十幾個頁面。日期元件那一類在二十張單裡涵蓋了幾個頁面?我沒有算過——但即使算了也不會讓人安心,因為真正的問題是另一件事:

問題單的數量,跟真實的問題數量沒有關係。
它只跟「有多少人、點了多久、點到哪裡」有關係。

所以那份上線準備度報告寫「完成度 65–70%、還要 15–25 天」的時候,那個數字建立在一個看不見的假設上:我們發現的問題,大致等於存在的問題。

而這個案子裡,那個假設不成立。

更難的是,它不成立這件事本身也沒有訊號。你看到問題單一輪一輪減少,會很自然地覺得「快收斂了」。但那也可以是另一種情況:測試人員把好點的地方都點過了,剩下的沒人想到要去點。

兩種情況,在報表上長得一模一樣。

小結

  • 35 張單其實是 18 個 bug——而重複的那些,是「一次做八十幾頁」種下的:一次失誤被複製了二十份
  • 所以小步快跑在 AI 時代權重更高:AI 把「一步做多少」變便宜了,但沒有把「錯了要重做多少」變便宜
  • 那 20 次不是「修了 20 次」,是四次隨機取樣各自撈到一部分
  • 因為三邊都拿不出那份「這一頁應該檢查什麼」的清單,測試成了唯一而且隨機的發現機制
  • 而它還有盲區:新人不知道什麼叫「不對」,看起來合理但其實不對的東西不會被回報
  • 問題單的數量,跟真實的問題數量沒有關係——它只反映測試投入了多少
  • 判準:做錯了還有沒有下游會發現? 沒有的話,那個位置是閘門,不是工站

明天

發現機制講完了。明天講另一半:這些單被撈上來之後,我們是怎麼處理的——以及為什麼一個原因可以變成七張單、修七次。

本系列所有案例均經去識別處理,不指涉任何特定客戶、系統或產業。


上一篇
Day 2 - 那個案子:四個月,最後客戶要求重做
下一篇
Day 4 - 修了 47 次,一條規則都沒留下
系列文
綠燈不等於做對:AI 開發的驗收工程 ——從兩個失敗的案子,到驗收交付13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言