iT邦幫忙

2026 iThome 鐵人賽

DAY 4
0
Claude AI

用 AI Agent 重構一套無框架的 legacy PHP 系統系列 第 4

Day 04:建立重構的「基準線」——分支策略與覆蓋率門檻

  • 分享至 

  • xImage
  •  

前言:AI 說「這樣改沒問題」,你要拿什麼驗證?

「AI 都已經跑過測試了,測試都綠燈,這樣還不夠嗎?」

這句話聽起來很合理,但漏掉一個關鍵前提:綠燈只證明「現有測試都還通過」,不代表「這段程式碼真的有測試在保護」。如果目標程式碼原本就沒有測試覆蓋到,AI 改完之後測試當然全綠——因為根本沒有測試會去踩到那段邏輯,綠燈只是「沒人看」的另一種說法。

這正好呼應 Day 01 立下的那句話:AI 給出的「已確認」結論,永遠只在它實際查過的範圍內成立。如果連「這段程式碼有沒有被驗證覆蓋」這個最基本的範圍都沒先確認,AI 的「已測試通過」就跟「已查證沒有真實流量」是同一種陷阱——看起來完整,實際上只是恰好沒人去戳破它。

所以在 AI 動手改任何一行程式碼之前,第一件事不是叫它開始改,而是先確認一件事:這段程式碼現在到底有沒有安全網?

今日目標

  • 理解「重構前先建立基準線」為什麼是不能省略的步驟
  • 分支策略:怎麼確保自己真的站在最新的起點上
  • 覆蓋率門檻:什麼程度的測試才算「有安全網」
  • 全站規模重構:怎麼用覆蓋率工具量化「AI 敢不敢動這一行」

分支基準:先確認自己真的站在起點上

第一件容易被忽略的小事:每次開始重構前,要先確認自己站在最新的主線分支上。這聽起來理所當然,但實務上常見的坑是——checkoutpull 這類指令失敗時不會大聲抗議,它會安靜地讓你留在舊分支上,繼續往下做事的人(不管是 AI 還是人)根本不會意識到自己是在一個過時的基礎上動手。

這裡的原則很簡單:每一步都要看實際輸出,不能假設「應該成功了」。這句話看起來像廢話,但當你把重構流程交給 AI 執行時,AI 很容易把一個指令的執行結果當成「應該沒問題」直接跳過確認,這正是「範圍不夠全面卻很有自信」的另一個具體版本。

覆蓋率門檻:能不能動手的先決條件

覆蓋率門檻是重構能不能動手的先決條件,不是動手之後才要補的東西。

具體規則是:

  • 重構前先確認目標程式碼現在有沒有測試覆蓋。沒有覆蓋,就先停手回報,不能在沒有安全網的狀況下重構——除非這次重構的目標本身就是「補測試」。
  • 對於一些關鍵的舊入口程式,要求的是能實際跑過完整流程的高階回歸測試,隨便一個測到片段邏輯的單元測試不算數——因為這類程式碼往往牽涉多個步驟串接,單元測試層級測不出「整條路徑走完是不是正確」。
  • 小範圍重構(單一模組、幾支檔案)可以靠讀程式碼、跑一次相關測試判斷有沒有覆蓋,用肉眼判斷就夠了;只有全站規模的重構,才需要動用覆蓋率工具。

用一組對照來看這條規則實際上在擋什麼:

❌ 沒有基準線就動手:
「這段函式很短,邏輯也不複雜,AI 改一改應該沒問題,
 測試跑一輪也是綠的。」
→ 沒人先確認「這段函式原本有沒有測試覆蓋到」,
   綠燈只是因為沒有測試會踩到這段邏輯

✅ 先建立基準線再動手:
「先查這段函式現在的覆蓋率——如果是 0,先停手,
 回報『這裡沒有安全網,要嘛先補測試,要嘛先取得你的同意才動』。」
→ 動手前明確知道自己有沒有安全網,而不是事後才發現改壞了也沒人看見

全站規模重構:用覆蓋率報告決定「真正能動的範圍」

當重構的規模拉大到「把某種寫法整批轉換成新寫法,全站有上百處要收斂」這種等級時,光靠肉眼判斷每一處有沒有測試覆蓋已經不可行——這時候需要覆蓋率工具產生的覆蓋率報告,逐行判斷:只改真正被測試覆蓋到的那一行,沒被覆蓋的維持原樣不動。這裡用的是 PHP 生態的 pcov,但這只是實現方式——JavaScript 生態有 nyc/istanbul、Python 有 coverage.py,「用覆蓋率報告逐行判斷能不能動手」這個原則跟語言無關,換工具就能套用

這裡有個容易被忽略的細節:同一支檔案裡,同一個舊寫法可能出現在兩個呼叫點,但只有其中一個被測試打到。這種情況下,正確做法是只改被覆蓋到的那個呼叫點,而不是「反正同一支檔案、順手全部改掉」。這種「順手」正是 AI 最容易犯的錯——覺得同一種模式應該一致處理,但一致處理的前提,是每一處都真的有驗證機制在後面接住。

這條規則把「AI 敢不敢動一行程式碼」,從一種憑感覺的判斷,變成一個可以量化的問題:這行有沒有被測試覆蓋。 有覆蓋率報告在手上,AI 就不需要自己判斷「這樣改應該安全吧」——它只需要回答一個更小、更客觀的問題:這一行的覆蓋計數是不是大於零。這正是整個系列想強調的核心:不是要求 AI 變得更謹慎、更聰明,而是把它需要判斷的範圍收斂到一個可以被驗證的具體邊界。

今日思考題

回想你自己手上正在重構的程式碼:如果現在要動一行邏輯,你能不能在 30 秒內查到「這一行現在有沒有測試覆蓋」?如果答案是「不知道,要另外去查」,那你交給 AI 動手時,AI 大概率也不會主動先查。

今日重點回顧

  • 測試綠燈不等於有安全網——可能只是沒有測試會踩到那段邏輯
  • 分支基準:每一步都要看實際輸出,不能假設「應該成功了」
  • 覆蓋率門檻是重構能不能動手的先決條件,不是事後才補的手續
  • 全站規模重構要靠覆蓋率報告逐行判斷,同一支檔案裡沒被覆蓋的呼叫點不要順手一起改
  • 核心命題的延伸:把「AI 敢不敢動手」從憑感覺判斷,收斂成一個可驗證的客觀問題

明日預告

明天要處理另一種容易被忽略的基準線落差:本機開發環境用的新版 PHP,跟正式環境/CI 實際跑的舊版 PHP 之間的相容性陷阱——本機測試全過,不代表換一個 PHP 版本還會是同樣的結果。


上一篇
Day 03:沒有安全網的重構有多危險——一次 AI 引入迴歸的真實案例
系列文
用 AI Agent 重構一套無框架的 legacy PHP 系統4
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言