昨天發了員工手冊,這位同事知道規矩了。但它還不知道自己要測的東西長什麼樣。
先別急著餵文件。這一集要回答的是更前面的問題:它到底在哪些時候需要產品知識?
這個問題的答案決定了你要準備多少東西。準備太少,它判不出真正的問題;準備太多,你會花兩個禮拜整理一份沒人看的文件。
新人訓練最直覺的做法,是把手上所有文件丟給他:需求、規格、API 文件、歷史決策。對真人來說,這頂多是浪費幾天,對這位同事來說,是三重浪費。
多數文件不能拿來判對錯,「本模組於 2023 年重構」是背景,不是判準,它不會讓任何一個 bug 現形。這些內容要嘛常駐 context 佔位置,要嘛根本沒被讀到,兩種都不划算。最花時間的是第三種:一份追求完整的文件永遠整理不完,而你在整理的那兩週,它一個 bug 都沒幫你找。
所以問題要倒過來問:它在哪些時候真的需要規格?答案不是「隨時」。有一整類缺陷,它光看畫面就判得出來,那類完全不用你準備;剩下那類,不管你讀幾遍,畫面都判不出來,那類才值得你寫。
先看第一類長什麼樣,再看它的天花板在哪裡。
先看一個真的抓到的例子。
我讓它去逛一個電商 demo 站的購物車,它回報了這個:
購物車頁面每一列商品的 Total 欄位一律顯示 $00.00,
不論單價與數量是多少;但頁尾的 Total 卻是正確加總的金額。
同一個畫面上兩組互相矛盾的金額。使用者無法確認自己被收多少錢。
判這個 bug 不需要看任何規格文件。不需要知道這家店賣什麼、免運門檻是多少、會員有沒有折扣。你只需要看到同一個畫面上有兩個數字在打架,就知道其中一定有一個是錯的。
這叫內部一致性,不需要外部規格就成立。同一類的還有幾種:
這也是為什麼我在那個 demo 站上跑了好幾輪找 bug,knowledge/ 資料夾始終是空的,照樣抓得到東西。
同一個站,另一個真的抓到的東西。
它用一般顧客帳號登入(id=2),拿自己的 token,直接呼叫另一個使用者的資料:
GET /users/1
Authorization: Bearer <顧客 id=2 的 token>
200 OK
{
"first_name": "John",
"email": "admin@practicesoftwaretesting.com",
"address": "Test street 123",
"city": "Utrecht",
"dob": "1980-01-01"
}
換一個 id 就讀得到別人的姓名、信箱、地址、生日。
現在把前面那些功能判準一條一條套上去:
| 判準 | 結果 |
|---|---|
| 內部一致性 | 畫面沒有自相矛盾 |
| 畫面對得上 API | 對得上 |
| console error | 沒有 |
| 狀態碼語意 | 200 配一筆合法的資料,完全正常 |
四條全過。若只看功能,它是一個會正常回資料的端點;但安全 oracle 會立刻亮起紅燈:一般顧客帶自己的 token,卻讀到了另一位使用者的個資,這是典型的物件層級授權異常。
通用安全判準足以把它列為高風險異常,但要確認產品承諾的授權模型,以及失敗時究竟應該回 403、404 或其他結果,仍然需要一句明確的規格:
使用者只能讀自己的資料;讀他人 id 應回 403 或 404。
這句話不在畫面上,也不在這次 API 回應裡。它在規格裡。沒有它,我們仍能依通用安全原則指出疑似越權,卻無法精確說明這個產品違反了哪一條約定、正確回應應該長什麼樣。
這就是天花板:通用判準能指出「壞掉」或「高度可疑」,產品知識才能進一步指出「違反哪一條約定」。

knowledge/ 那六行就是穿過天花板的梯子。
而成熟產品裡許多高價值缺陷,都是後面這種。授權邊界、業務規則、狀態機的合法轉換 —— 這些東西壞掉的時候,畫面通常好好的。
knowledge/ 存在的唯一理由這位同事需要一個地方,放「這個產品說好要怎樣」。
那個地方叫 knowledge/。它服務的對象很明確 —— 一支叫 test-oracle 的 skill。test-oracle 的工作是判斷「這個現象到底是不是 bug」,它手上有一整排判準,其中一條叫規格 oracle,而規格 oracle 的內容就從 knowledge/ 讀。
沒有 knowledge/,test-oracle 就只剩通用那幾條,判得出「壞掉」,判不出「不符合約定」。
我用的受測目標是公開的電商練習站。很容易以為這種東西沒有規格可寫 —— 我一開始也這樣想,所以 knowledge/ 空了好幾輪。
錯了。前面那個越權讀取就是它抓到的,而我當時判不出來,因為沒有任何地方寫著「使用者只能讀自己的資料」。
補完之後也不長,就這樣:
## 業務規則(會變成 oracle 的判準)
- 使用者只能讀寫自己的資料;讀他人 id 應回 403 或 404
- 購物車數量為 1 到 99 的整數,超出範圍應該擋下並顯示原因
- 每一列的 Total = 單價 × 數量;所有列相加等於頁尾 Total
- 註冊時的密碼規則提示不得洩漏既有帳號是否存在
- 登入連續失敗達門檻應鎖定帳號,回 423
## 名詞表
- invoice = 已完成結帳的訂單紀錄,一張對應一次結帳
六行。 花不到十分鐘,但它讓 test-oracle 從「只能判壞掉」變成「判得出違反了哪一條」。
判斷要不要建的標準不是「產品大不大」,是這個產品有沒有任何一條規則,是光看畫面看不出來的。幾乎每個產品都有,只是你太熟了,熟到忘記那是知識。
新手最常犯的錯,是把 knowledge/ 寫成操作手冊:
## 結帳流程
1. 點右上角購物車圖示
2. 點 Proceed to checkout
3. 填收件資訊,按下一步
4. 選付款方式
這種東西一行都不要寫。它自己會操作,這是它最強的能力之一,你昨天已經給它眼睛了。寫這個等於教魚游泳,而且畫面一改就過期。
要寫的是判準:
## 業務規則(會變成 oracle 的判準)
- 折扣券不可與會員價疊加
- 數量必須為 1 到 99 的整數
- 未付款訂單保留 30 分鐘後釋放庫存
- 滿 1000 免運,折扣後金額不計入門檻
每一條都是「應該怎樣」,都可以拿去跟畫面上看到的比對,都能得出「符合」或「違反」。
判斷標準很簡單:這句話能不能拿來判對錯?不能的話它不屬於這裡。
config/ 的分界:換環境會不會變還有一個常見的混淆。這兩份檔案長得很像,但屬於不同層:
config/product-context.md |
knowledge/product-overview.md |
|
|---|---|---|
| 回答 | 怎麼連上產品 | 產品是什麼 |
| 內容 | base URL、帳密變數名、Playwright 設定 | 業務規則、名詞表、授權模型 |
| 換一個環境 | 會變 | 不會變 |
分界線就是最後一列:換環境會變的是設定,不會變的是事實。
staging 跟 production 的網址不一樣,那是設定。「折扣券不可疊加」在兩個環境都成立,那是事實。
API 照同一條線切。base URL、認證方式、憑證變數名、契約檔位置在 config/;這個 API 承諾什麼(錯誤結構長怎樣、404 還是 200 空陣列、誰能讀誰的資料、哪些端點宣稱冪等)在 knowledge/。
knowledge/ 有三種規模,照你的產品挑一種,不要一開始就蓋大的。
一、小產品 —— 一份 product-overview.md
複製範本填一填就好。核心模組一張表、業務規則一串條列、名詞表幾行。多數專案停在這裡就夠。
二、中型 —— domains/ 每個模組一份
規則多到一份檔案讀起來很累的時候,拆成 domains/checkout.md、domains/account.md。好處不只是好維護 —— skill 可以只載入需要的那一份。它在測結帳,就不用把會員模組的規則也讀進來付一次錢。
三、大型或文件常變 —— 指向活文件
規格散在 Confluence、Notion 或另一個 repo,而且每週都在改。這時候複製一份下來只會過期,改用檢索或 MCP resource 指過去。
沒有任何專案該從第三種開始。從第一種開始,撐不住再往上走。
knowledge/ 裡的真實內容很可能包含內部規格、未公開的業務規則、甚至客戶名稱。
所以規則是:只 commit 範本,真檔進 gitignore。
knowledge/
README.md 進版控
product-overview.example.md 進版控
product-overview.md 不進版控 ← 你的真實內容
domains/
checkout.example.md 進版控
checkout.md 不進版控
config/ 也是同一套規則,理由更直接 —— 那裡面有網址跟帳密變數名。
不是「去整理一份完整的產品文件」。是三個判斷:
config/,不會變的留 knowledge/。想清楚這三題,你的 knowledge/ 會很薄。薄是對的。 它的價值在於每一條都能拿來判斷,不在於它有多完整。
一個檢查方法:把你寫的每一條唸一遍,問「如果產品違反這條,我看得出來嗎?」看得出來的那些是通用判準的守備範圍,不用寫,看不出來的才值錢。
一個現象
│
▼
通用判準先過一遍
內部一致性|畫面對 API|console|狀態碼
│
┌───────────────┴───────────────┐
▼ ▼
有一條沒過 功能判準全過
│ │
▼ ▼
判得出「壞掉」 安全判準仍可能亮紅燈
或「高度可疑」 但預期行為還不夠精確
│ │
│ ▼
│ 規格 oracle 讀 knowledge/
│ 「使用者只能讀自己的資料」
│ │
└───────────────┬───────────────┘
▼
寫進 knowledge/ 的三道篩子
看畫面看不出來?能判對錯?換環境不會變?
│
▼
三題都是 → 寫;有一題不是 → 不寫
通用判準抓得到「壞掉」或「高度可疑」,產品知識則補上「違反哪一條約定」與「正確結果應該是什麼」。所以 knowledge/ 只放判得出對錯的句子,操作步驟不要寫進來。薄是對的:六行就讓 test-oracle 從「只能指出異常」變成「判得出違反了哪一條」。
現在它知道規矩、也知道產品長什麼樣了。但它還進不去 —— 產品需要登入,而帳號密碼是一件要非常小心處理的事。
明天處理權限。
@import 語法) - 用 @path 把產品文件掛成常駐知識