「這個系統測試寫得挺仔細的,應該沒有明顯的覆蓋漏洞吧?」
昨天看到的 sitemap 測試涵蓋了 V1、V2 兩套介面版本,看起來很完整。但今天要指出一件容易被誤會的事:昨天測的 /sitemap,跟這個系統另一支真正輸出給搜尋引擎讀的 /sitemap.xml,其實是完全不同的兩個東西——而後者,反而完全沒有 Feature 測試直接驗證它。
/sitemap 是給人看的網站導覽頁面——列出頁面的階層結構,方便使用者瀏覽整個網站的頁面樹。這個路由昨天看過,V1、V2 兩套介面版本都有 Feature 測試覆蓋。
/sitemap.xml 則完全是另一回事:它輸出的是符合搜尋引擎規格的 XML 格式檔案,讓 Google 之類的搜尋引擎爬蟲讀取,用來索引網站上所有可以被搜尋到的頁面。這個端點的正確性,直接關係到網站在搜尋結果裡的能見度——如果這個端點壞了,使用者完全不會發現(因為根本沒有人會手動打開這個網址看),只有搜尋引擎的收錄狀況會悄悄變差。
這個系統確實出過一次跟 /sitemap.xml 有關的真實事故:這個端點回傳的 Content-Type 不正確,導致 Google Search Console 沒辦法正確解析這份 sitemap 檔案。修復方式包含把這個路由移出原本會處理 session 邏輯的中介層(避免不必要的邏輯干擾 XML 回應)、改用串流回應搭配正確的 Content-Type header、以及在指令產生 sitemap 檔案時強制使用正確的網址協定。
搜過整個測試目錄,會發現一件耐人尋味的事:昨天看到的 SitemapTest.php(V1、V2 各一支)測的都是 /sitemap 這個給人看的頁面,完全找不到針對 /sitemap.xml 這個真正輸出 XML 給搜尋引擎讀的路由的 Feature 測試——沒有測試驗證它的 Content-Type 對不對、輸出的內容是不是合法的 XML 格式。
這不是「這個系統測試寫得不夠仔細」這麼簡單的結論。這正是「測試覆蓋不是均勻分布」這件事最真實的樣貌:/sitemap 這個頁面,開發者跟使用者三不五時都會手動點開看看畫面對不對,出了問題很快就會被發現,自然也比較容易被想到要補測試;/sitemap.xml 這種只有搜尋引擎機器人會去讀的端點,人類幾乎不會主動點開檢查,出了問題往往要等到過一段時間,觀察搜尋引擎的收錄狀況異常,才會被追查出來——這次的 Content-Type bug,就是靠人工事後排查才發現的,不是靠測試提早攔下來的。
**「這個系統的測試寫得多、寫得細」跟「這個系統重要的地方都被測試保護著」,是兩件不一定同時成立的事。**測試覆蓋率的分布,往往反映的是「開發者平常注意力放在哪裡」,而不是「哪裡真正重要」。一個只有搜尋引擎機器人會碰、平常沒有人會手動驗證的端點,反而更需要自動化測試補上這層保護——因為它出問題時,不會有人第一時間發現。
回頭看昨天討論的「該不該為了 DRY 抽共用測試邏輯」,跟今天這個「重要但沒人記得測」的端點放在一起看,其實指向同一件更根本的事:測試該花在哪裡,不該只看「這裡程式碼多不多」或「這裡我平常會不會手動測」,而該問一句「如果這裡壞了,會有誰、多快發現?」——答案是「幾乎沒有人會很快發現」的地方,往往才是最該優先補測試的地方。
回想你維護的專案,有沒有一個端點或功能,是「只有機器(爬蟲、第三方系統、排程任務)會用到、平常沒有人類使用者會手動檢查」的?它有沒有對應的自動化測試?如果它壞了,你估計要多久才會被發現?
/sitemap(給人看的導覽頁)跟 /sitemap.xml(給搜尋引擎讀的 XML)是完全不同的兩個路由,職責不一樣/sitemap.xml 的 Content-Type bug,是靠人工事後排查發現的,不是靠測試提早攔下/sitemap,/sitemap.xml 這個更容易被忽略、但同樣重要的端點反而沒有對應測試明天要看一種不同類型的測試:首頁這種組合了多個區塊、依賴橫跨全站設定值的頁面,測試前要先準備多少「全站狀態」才測得起來。