為什麼零 Bug 的程式碼是錯誤的目標
每一套系統都存在還沒有人踩到的缺陷,而當明顯的問題被清掉之後,找出下一個的成本會急遽上升。超過某個點之後,多花一小時去獵捕缺陷,價值會低於把同樣一小時拿來讓失敗更容易被發現、也更便宜地修好。
第二個問題出在文化。當零 Bug 被訂為目標,一個 Bug 就變成需要交代的過失,而不是可以拿來行動的資訊,於是大家對它愈來愈不出聲。
三個真正可行的目標
不重複發生
同一個 Bug 只發生一次。每一次修復都留下一道檢查。
做得到,而且會持續累積。
在使用者之前發現
把發現問題的時機從正式環境往前移到 pull request。
可量測:有多少比例是在內部就攔下來的。
修復成本低
從失敗到修好所花的時間,而這主要取決於失敗報告的品質。
為什麼第一個最重要
一個從不讓同一個 Bug 出貨兩次的團隊,本質上每個月都會變得更好。這只需要一個習慣:修好東西的時候,留下一道檢查。多數團隊修掉 Bug、關掉票,卻沒有留下任何紀錄,說明這段行為曾經需要被保護。
該量測什麼
追蹤在發布前就被找到的缺陷佔比,以及從失敗到修好的時間。只有真的有東西變好,這兩個數字才會動,而且都沒辦法靠多寫測試來灌水,這正是它們有用的地方。測試數量和覆蓋率百分比要多少有多少,卻幾乎說明不了什麼。
為什麼團隊還是繼續追
知道這個目標是錯的,並不會讓人停止瞄準它;而背後的原因值得理解,因為它是結構性的,不是單純的天真。
Bug 看得見,預防看不見。一個流到客戶手上的缺陷會有一張票、一個名字和一個負責人。發布前被攔下來的那十二個什麼都沒有,因為什麼事都沒發生。於是一季下來看得到的紀錄就是一份失敗清單,而面對一份失敗清單,最自然的反應就是要求失敗少一點。
解法是讓預防也看得見。在回報有多少缺陷外流的同時,也一併回報有多少缺陷在發布前就被攔下來。前面那個數字通常大得多,看見它會讓討論從「我們為什麼一直有 Bug」轉向「這個比例有沒有在往好的方向走」,而後者才是有用答案的問題。
實際做起來是什麼樣子
每個 Bug 都配一道檢查。檢查在每一次變更時執行,而不是等到發布前才跑。失敗回報的形式,要讓負責修的人不必重新推敲來龍去脈就能動手。
終端機
npm install -g @testsprite/testsprite-cli
testsprite setup
如果不想在本機安裝,儀表板也涵蓋了同樣的範圍;完整的指令則收錄在 CLI 儲存庫。
觸發方式比機制更重要。把它接到你的部署事件上,代表每一次變更都會被檢查,不需要任何人特地決定要不要跑; GitHub App 可以從儀表板做到這件事,而 GitHub Actions 的步驟則是在你的工作流程裡做到。
TestSprite 如何支援這三個目標
「不重複發生」是它支援得最直接的一項。重現這個 Bug 的測試案例會留在專案裡,並在每一次變更時執行,所以修復本身就留下了一道檢查,不需要有人記得要去寫。
「在使用者之前發現」是節奏的問題。測試涵蓋範圍是從你的產品產生出來的,並在 pull request 上執行,這讓發現問題的時機從正式環境往前拉回到造成問題的那次變更。
「修復成本低」取決於失敗報告。一次執行回來的內容是:嘗試了什麼、應用程式實際做了什麼,以及兩者在哪裡分岔,所以負責修的人——愈來愈常是 coding agent——是從證據開始,而不是重新拼湊事情經過。
零 Bug 有可能做到嗎?
對於規模小、有形式化規格的系統,可以很接近,但代價高到幾乎沒有人划得來。對一般產品來說,不行。
合理的缺陷率是多少?
拿你自己的趨勢來比,而不是拿業界數字來比。方向比高低重要。
測試做得愈多,Bug 就愈少嗎?
到某個程度之前是。過了那個點,多加的測試只會增加維護成本,卻不會增加有用的訊號,尤其是當它們重複了你已經涵蓋的部分。
我們該追蹤 Bug 數量嗎?
追蹤外流的缺陷,以及修復所需的時間。原始數量會在回報品質變好時跟著上升,所以它是個很差的訊號。
最有槓桿效果的單一習慣是什麼?
每次修好東西,就留下一道檢查。這是唯一會持續累積的習慣。