iT邦幫忙

2026 iThome 鐵人賽

DAY 16
0
Modern Web

一個活了六年的 Vue 2 後台,升級到 Vue 3 的那兩年系列 第 16

Day 16|每 100 個測試站抓到的問題,有 1 到 2 個會溜到正式環境

  • 分享至 

  • xImage
  •  

模組三|遷移執行法與驗收(Day 12–16)

我們團隊修 bug 的時候,commit 訊息會標一個階段標籤:這個問題是在哪一關被抓到的。

六年下來,這變成一份免費的統計資料。我把兩個新專案的標籤數出來:

在哪一關被抓到 專案 A 專案 B
TEST(開發自己的測試站) 465 893
FAT(內部驗收) 12 44
UAT(使用者驗收) 11 11
正式環境 11 8

兩個專案合起來:1,455 個被記錄的問題,其中 19 個是在正式環境才被發現的(約 1.3%)。

這是一個漏斗,而且它在運作。今天講這個漏斗每一層在擋什麼。

先講清楚那幾個縮寫

我承認我剛進公司的時候,看到 TEST、FAT、UAT 只覺得是「好幾個測試站」,差別大概是「越後面越接近正式」。

這個理解是錯的。 它們的差別不在「有多接近正式環境」,在誰在測、他關心什麼

  • TEST:開發自己的地盤。功能做完先丟這裡,工程師和測試人員在這裡跑案例。
  • FAT(Factory Acceptance Test,廠內驗收):內部代表使用者角色來驗,通常是產品、客服、營運。
  • UAT(User Acceptance Test,使用者驗收):真實使用者或其代表來驗。
  • 正式環境:真的在跑生意的那一套。

用一頓飯來理解

TEST 是廚師自己試味道。 他關心的是:鹹淡對不對、有沒有煮熟、擺盤有沒有歪。他知道這道菜「應該」是什麼樣子。

FAT 是店長試菜。 他關心的是:這道菜符合我們菜單上的描述嗎?成本控制得住嗎?出餐速度可以嗎?他懂餐廳,但他不是客人。

UAT 是找熟客來試吃。 他不管你的成本和動線,他只會說:「這個份量對一個人來說太多了」「醬汁很好吃但麵有點軟」。

三種人挑出的毛病完全不同,而且後面的人挑的毛病,前面的人通常想不到。

這就是為什麼不能跳關。TEST 抓的是「壞掉」,UAT 抓的是「不合用」——而「不合用」是寫不出測試案例的。

環境設定要跟得上

有幾種驗收,就要有幾套環境。這件事在新系統是靠設定檔支撐的。

新專案有六到七個環境設定檔(開發、測試、正式、容器化、打包分析、本機覆蓋),而建置指令的差別只剩「模式」:

vite build                # 正式
vite build --mode test    # 測試
vite build --mode docker  # 容器化

對照舊系統:它只有兩個設定檔,而真正的環境差異(後端位址、代理規則)寫在建置設定檔裡,切換靠人工註解(Day 11 講過)。

這個差別在重構期特別關鍵,因為你會需要一件事:讓新舊兩套系統指向同一套後端。

沒有這個能力,你就沒辦法做功能對照,而功能對照是重構驗收的核心,下一段講。

重構的驗收,跟一般開發不一樣

這是我覺得最少人講、但最重要的一段。

一般開發的驗收問:「這個新功能對不對?」
你有規格、有設計稿、有驗收條件。照著檢查就好。

重構的驗收要問:「這個舊功能,有沒有變得不一樣?」

而這個問題沒有測試案例可以照著跑,因為「原本就是這樣」從來沒有人寫下來。

舉個我們實際遇到的類型:

舊系統的某個查詢,日期欄位留空的時候會預設查最近七天。

新系統重寫之後,留空就是不限日期。

兩個行為都很合理。沒有任何文件寫過該是哪一種。而使用者切換過來之後,會覺得「新系統怎麼變慢了」,因為他習慣留空,而現在那會撈出全部資料。

這種問題有三個特徵,每一個都讓它很難被抓到:

  1. 不是 bug,程式碼完全按照寫的跑
  2. 測試案例抓不到,因為沒有人把那個預設行為寫進規格
  3. 只有真實使用者會發現,因為只有他有那個使用習慣

我們的做法:主動做功能對照

同一個模子壓出來的兩片,我疊起來舉高對光看,露出來的那一圈就是差異

所以我們後來的規則是:搬完一個模組,主動跑一次新舊對照,而不是等被回報。

具體做法很土:把舊系統和新系統開在兩個瀏覽器分頁,同一組查詢條件各打一次,比對結果。差異列出來給業務確認:是刻意改的,還是搬漏了。

這件事聽起來很費工,但它把問題攔在 FAT 之前。而攔在 FAT 和攔在正式環境,成本差一個量級。

前後端不同步的時候

我知道這個輪子是紙板做的,所以我特地綁了一條長到會絆倒人的布條

還有一個重構期的常見狀況:前端做完了,後端還沒好。

這時候你有兩個選擇:等,或是先用假資料做完。

我們的做法是後者——先注入假資料把畫面和流程做完,等後端上線再換掉。

但這裡有個規則很重要:

「移除假資料」這件事,要開一張獨立的票。

如果你只是在程式碼裡留一個 // TODO: 等後端 的註解,那個假資料有很高的機率會活到正式環境。因為:

  • 寫的人記得,但他不一定是後端上線那天在的人
  • 測試站的資料看起來是正常的(因為假資料就是照正常的樣子做的)
  • 除非有人專門去比對,否則畫面上完全看不出來那是假的

我們有一個具體的實踐是:假資料要明顯到會被發現(例如金額固定用一個不可能出現的數字)。寧可醜,也不要真到讓人忘記它是假的。

代價

一、關卡越多,交付越慢。 一個小改動要走完 TEST → FAT → UAT,可能是兩週。所以要有分級:不是每個改動都要走完整流程,緊急修復要有快速通道,但快速通道要有紀錄,否則它會變成預設路徑。

二、標籤統計有偏差。 前面那些數字來自 commit 訊息的人工標籤,會有人忘記標、也會有人標錯。趨勢可信,絕對值不要當成品質指標拿去比較。我自己也是把它當「漏斗有沒有在收窄」的參考,而不是 KPI。

三、多環境要有人維護。 六七個設定檔代表六七套可能失同步的東西。我們遇過「測試站好好的、容器化環境壞掉」,原因是某個設定只加在其中一邊。

帶走什麼

  1. 環境不是「好幾台伺服器」,是「好幾種人的懷疑」。 每一關過濾的是不同種類的錯誤,跳過任何一關,那類錯誤就會直接抵達使用者。
  2. TEST 抓「壞掉」,UAT 抓「不合用」。 後者寫不出測試案例,所以不能用「我們測過了」來取代它。
  3. 重構的驗收要問「舊功能有沒有變得不一樣」,而不是「新功能對不對」。 而這個問題只能靠主動的新舊對照,不能靠等回報。
  4. 假資料要開獨立的票來移除,而且要醜到不會被忘記。 註解攔不住它上線。
  5. 漏斗數字看趨勢就好。 如果 TEST 和 UAT 的數量差不多,代表你的測試站根本沒在攔東西,那才是這組數字真正的用途。

模組三到這裡結束:怎麼切第一刀、怎麼在共存期活下來、哪些不用搬、什麼時候改名、以及怎麼確保東西不會壞到使用者手上。

明天開始模組四,進到系統內部。Day 17 講路由與選單——我們換了框架,但沒有換心智模型。而重寫之後,程式碼行數變成原本的兩倍以上。


上一篇
Day 15|566 個 API,17 種命名方式,而我忍住沒有邊搬邊改
下一篇
Day 17|重寫完,路由的程式碼從 328 行變成 704 行
系列文
一個活了六年的 Vue 2 後台,升級到 Vue 3 的那兩年17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言