「使用者已經附上完整的環境資訊、重現步驟、錯誤訊息了,這樣應該可以直接動手修了吧?」
這句話聽起來合理,但一份寫得再詳細的 issue,回報的永遠是「症狀」——使用者觀察到的現象,不是「病因」。今天用 PHPUnit & Pest Test Explorer 這個專案裡一個真實的 open issue,走一次「從症狀描述到定位真正根因」的完整過程,看看 AI 在這個過程裡該扮演什麼角色、又容易在哪裡走錯方向。
這個 issue 目前還是 open 狀態,標題是「無法執行單一測試」。回報者提供的資訊相當完整:
Test file "/home/<使用者路徑>/project/tests/Controller/AccountControllerTest.php" not found
phpunit.paths 這個路徑對應設定(把主機端的 ${workspaceFolder}/project 對應到容器內的 /project)面對這份回報,AI 第一件該做的事,不是立刻去猜「大概是哪裡的程式碼寫錯了」,而是先把回報者提供的資訊拆解成幾個清楚的欄位:
/home/...),不是設定裡對應到容器內的路徑(/project/...)phpunit.paths 這個路徑對應機制存在,但看起來沒有在「執行單一測試」這個操作上生效光是把這幾點列出來,就已經比「使用者說跑不動、我來看看哪裡壞了」這種籠統的起手式,更接近問題核心——因為錯誤訊息裡明確出現了「用的是主機路徑,不是容器路徑」這個具體線索,這代表問題很可能不在「測試邏輯本身」,而在「路徑轉換這個環節,在某個操作路徑上沒有被套用」。
用一組對照,看兩種定位方式的差異:
❌ 憑經驗直接猜:
「Docker 環境下路徑常常出問題,應該是 phpunit.paths
設定寫錯了,請使用者檢查一下設定值。」
→ 沒有從錯誤訊息本身的線索出發,
跳過了「為什麼『執行全部』正常、『執行單一』卻不正常」這個關鍵差異
✅ 從症狀線索逐步縮小範圍:
「能執行全部測試,代表 phpunit.paths 這個對應機制本身是有效的;
不能執行單一測試,代表問題出在『執行單一測試』這條路徑上,
這條路徑很可能沒有呼叫到跟『執行全部』相同的路徑轉換邏輯。
下一步應該去確認:擴充套件裡『執行全部』跟『執行單一』
這兩個操作,是不是各自獨立組出要傳給 PHPUnit 的檔案路徑,
而不是共用同一段轉換邏輯。」
→ 從「能動 vs 不能動」的差異出發,把懷疑範圍
收斂到「這兩條操作路徑有沒有共用轉換邏輯」這個具體問題
「兩個操作的差異在哪裡」永遠比「哪裡看起來可疑」更接近真正的根因——這正是這個系列反覆提到的模式的另一種樣貌:AI 給出的懷疑方向,如果沒有從症狀本身的具體線索出發,很容易變成「聽起來合理,但沒有真的縮小範圍」的空泛猜測。
這個 issue 底下有第二位使用者留言「Same issue here」,附上的環境資訊(PHPUnit 版本、執行環境)跟第一位回報者不完全一樣,但都是「Docker Compose 環境下無法執行單一測試」。
這裡有個容易被忽略的陷阱:「症狀相同」是開始調查的合理理由,但不是「這兩個人踩到同一個根因」的證明。 在正式定位問題、寫修復程式碼之前,比較穩健的做法是先確認:兩個人的重現步驟、路徑設定結構是否真的一致,還是只是「都在 Docker 環境、都無法執行單一測試」這種表面相似,底層可能是兩個不同的成因(例如一個是路徑轉換沒生效,另一個是路徑轉換生效了但轉換規則本身有 edge case)。這個判斷方式,跟 Day 04 講過的「表面症狀相似不代表是重複回報」,其實是同一個原則在不同情境的展現。
回想你上一次拿到一份「症狀描述完整」的 bug 回報:你是直接從症狀猜可能的原因,還是先把「能動的操作」跟「不能動的操作」的差異列出來,再從這個差異反推可疑的環節?
明天要看另一個真實案例:一個跟覆蓋率報告檔案路徑找不到有關的 bug,怎麼一步步從「檔案找不到」這個表面訊息,查到真正的路徑組裝邏輯出了什麼問題。