Day 10|從 UI 追到 API:教同事觀察 Network
前言
昨天是被動讀已經留下的證據,東西都在檔案裡,差別只在開哪一份。今天換一種姿勢:挑一個 UI 動作,主動追它到底做了什麼,然後面對昨天四種來源全部乾淨、卻確實有缺陷的那種情況。底下的數字都是 2026-08-02 實跑量到的,證據在 output/evidence/20260802-withbugs-network/,對照組在 output/evidence/20260802-toolshop-checkout/。
為什麼要追到 network
UI 是最會騙人的一層。畫面上的每一個數字、每一個狀態,都可以是前端自己畫的。徽章從 0 變 1,可能是因為後端建了購物車,也可能只是前端把一個變數加一。這兩件事在畫面上長得一模一樣。
不追到 network,你驗的就是前端的渲染邏輯,不是產品的行為。而昨天那四種來源有個共同的盲點:它們都只回答「發生了什麼」,不回答「什麼沒發生」。截圖拍得到多出來的東西,拍不到少掉的請求;console 印得出報錯,印不出沉默;network 列得出送出去的每一筆,列不出本來該送卻沒送的那一筆。
缺席不會自己現身,所以今天要多帶一樣工具:基準線。
受測站是 Toolshop,而且要用它的兩個版本:
| 版本 | 網址 |
|---|---|
| 乾淨版 | https://practicesoftwaretesting.com/ |
| 刻意植入缺陷版 | https://with-bugs.practicesoftwaretesting.com/ |
同一個產品、兩個環境,這件事本身就是方法。
實驗:按下 Add to cart,network 一個請求都沒有
登入 with-bugs 版,開商品頁,按 Add to cart 前後各導出一次 network:
playwright-cli network --raw > before-addcart.log
playwright-cli click e103 # Add to cart
playwright-cli network --raw > after-addcart.log
diff <(grep '=>' before-addcart.log) <(grep '=>' after-addcart.log)
結果:
| 請求數 | |
|---|---|
| 按之前 | 2 |
| 按之後 | 2 |
| 差集 | 空 |
一個請求都沒有發出去。
但畫面說成功了:
導覽列的購物車徽章從 0 變 1,進到結帳第一步也看得到那一列商品。
沒有 toast 說失敗、沒有 console error、沒有非 2xx,昨天那四種來源全部乾淨。
那你怎麼知道少了什麼
比對乾淨版。同一個動作,同一天早上跑過:
[POST] https://api.practicesoftwaretesting.com/carts => [201] Created
[POST] https://api.practicesoftwaretesting.com/carts/01kz0rxps29tszvwpdaprxhggm => [200] OK
兩支請求。with-bugs 版是零支。
你得先知道「這個動作本來該發幾支請求」,才看得出來它沒發。而那兩支 POST /carts 是三個小時前留下的,當時看起來只是一筆無聊的紀錄。所以昨天最後那條結論要往前推一步:不只要留證,還要留正例。
這一輪還沒有系統性地建立這份基準,靠的是人記得早上跑過乾淨版。要變成流程,得有地方存它,那是第三週 charter 的事。
這比「回 500 被前端吞掉」更難抓
原本設想的場景是:送出後 UI 顯示成功 toast,但那支 POST 其實回 500,被前端吞掉了。
那種還算好抓,network 上有一筆紅的,掃一眼就看到。
這裡是什麼都沒有。掃 network 找紅色的人,會判它通過。
反過來說,這一輪也沒抓到「請求發了但回應被吞掉」的實例。with-bugs 這條是零請求,比較極端,真實產品更常見的是回了 4xx 或 5xx 但前端不顯示。
跑這一輪的指令長這樣:
/evidence-package 在 with-bugs 版登入後加一件商品進購物車,比對按鈕前後的 network 差異
/evidence-package 同一個動作在乾淨版跑一次,列出兩邊各發了哪些請求
/api-evidence 用已存在的 email 打 users/register,比對兩個版本的錯誤訊息
授權依據:charters/toolshop-login-cart.yaml。不刪任何資料、不取得 admin token、不列舉他人資料、端點單發不連打。
對照組:同一張表自己跟自己打架
結帳第一步:
| 欄位 | 顯示 |
|---|---|
| Price |
$14.15
|
| Total(那一列) |
$00.00
|
| Total(表尾) |
$14.15
|
這一筆不用比對基準線。同一張表裡,列小計是 0、表尾總計是 14.15,光看內部一致性就違規。
兩種缺陷放在一起,剛好是一組對照:
| 加入購物車沒發請求 | 小計 $00.00 | |
|---|---|---|
| 怎麼發現 | 跟乾淨版比對請求清單 | 讀同一張表的兩個數字 |
| 需要基準線嗎 | 要 | 不要 |
| 只看畫面找得到嗎 | 找不到 | 找得到 |
$00.00 的成因今天沒有追。是前端算錯還是 API 回錯,要看那支請求的 response body,這一輪只記錄了現象。
端點側:兩筆用畫面永遠看不到的
一、註冊的錯誤訊息洩漏密碼提示。
curl -X POST https://api-with-bugs.practicesoftwaretesting.com/users/register \
-H "Content-Type: application/json" \
-d '{"email":"customer@practicesoftwaretesting.com", ...}'
{"email": ["User already registered - Your password hint is: Name of your cat!"]}
只要知道 email 就拿得到別人的密碼提示。乾淨版同樣的請求只回 "A customer with this email address already exists."
二、token 有效期差了五萬倍。
把登入拿到的 JWT 解開,算 exp - iat:
| 版本 | 有效期 |
|---|---|
| 乾淨版 | 300 秒(5 分鐘) |
| with-bugs | 15,600,000 秒(180.6 天) |
這兩筆的共同點:畫面上完全看不到。 密碼提示被前端過濾掉了才顯示,token 有效期根本不會顯示在任何地方。要看見它們,你得自己去打端點、自己去解 JWT。
有效期這條只驗了顧客帳號,其他角色是不是也一樣沒查。
順手撿到的
登入成功了,導覽列說查無使用者。這一筆不在今天的目標裡,先記下來。
- 已登入狀態,導覽列顯示
User Data not found GET /broken.png→ 404- 文案:
Contakt、Serch、Reltded products - 結帳表格有兩欄都叫
Total
小結
挑一個 UI 動作,動作前後各導一次 network,先看差集;有差集就往下讀狀態碼與回應內容,差集是空的就換乾淨版跑同一個動作,拿它當尺量出少了哪幾支請求;畫面上根本不顯示的那些(密碼提示、token 有效期),要另外直接打端點。三條路走完,你手上才有「產品實際做了什麼」,而不是「畫面說它做了什麼」。
一個 UI 動作
│
按之前/按之後各導一次 network
│
▼
diff 請求清單
│
┌─────────────┴─────────────┐
▼ ▼
有差集 差集是空的
│ │
▼ ▼
讀狀態碼與回應內容 跟乾淨版比對請求清單
(200 也可能是錯的) (缺席只有靠基準線看得見)
│ │
└─────────────┬─────────────┘
▼
畫面永遠不顯示的,直接打端點、自己解 JWT
▼
UI 說的 ≠ 產品做的,以後者為準
UI 說成功不代表有東西送出去,徽章變了、列表有了,可能全都是前端自己畫的。缺席也不會自己現身,看出「少發了一支請求」只能靠基準線,所以乾淨版不是拿來測的,是拿來當尺的。而掃紅色抓不到這一種:沒有 4xx、沒有 5xx、沒有 console error,什麼都沒有才是問題。
下一步
這兩天蒐到的東西夠多了:截圖、console、network、兩個環境的請求清單、端點側的原始回應。
但它們現在是散的。明天要處理交棒:一份證據包要湊到什麼程度,別人才不必重跑一次就看得懂你的結論。標準只有一條,每個結論都要有一份指得到的檔案接住它。
---
參考資料
- Playwright — Network - 觀察、攔截、mock 請求
- Playwright API — Request/Response - 拿到 request 與 response 的細節
- Chrome DevTools — Network - 給讀者對照手動除錯的經驗
- MDN — HTTP response status codes - 判斷回應正不正常的第一層依據
- JSON Web Tokens -
iat、exp的意義,本篇算有效期的依據 - OWASP — Session Management Cheat Sheet - 為什麼 token 有效期要短
- OWASP — Authentication Cheat Sheet - 為什麼錯誤訊息不該洩漏帳號是否存在或密碼提示
- testsmith-io/practice-software-testing - Toolshop 兩個版本的原始碼
- 本篇證據
output/evidence/20260802-withbugs-network/、對照組output/evidence/20260802-toolshop-checkout/- with-bugs 與乾淨版兩邊的請求清單原始檔