 AI 告訴你「測(cè)試全過(guò)」時(shí):3 次被拆穿的假警報(bào))
讓 AI Agent 幫你寫測(cè)試、跑測(cè)試你多半收到過(guò)一句令人安心的提示「全部通過(guò)All Passed」。但很多時(shí)候事后查驗(yàn)才會(huì)發(fā)現(xiàn)這句承諾漏洞百出。這篇文章記錄了三次「全部通過(guò)」被無(wú)情拆穿的過(guò)程。所有的數(shù)字和日志都真實(shí)存在未作修改。文章最后總結(jié)了三個(gè)針對(duì)「假通過(guò)」的硬核解法。背景提示事情發(fā)生在一臺(tái) Windows 測(cè)試機(jī)上幾個(gè) AI Agent 正分頭協(xié)作將一個(gè)名叫 Polter 的多 Agent 終端應(yīng)用移植到 Windows 平臺(tái)。第一次「假摔」號(hào)稱 16 個(gè)通過(guò)其實(shí) 3 個(gè)根本沒(méi)碰到當(dāng)時(shí)的界面上排布著 17 個(gè)標(biāo)簽Tab。測(cè)試 Agent 寫了一段腳本挨個(gè)去點(diǎn)擊這 17 個(gè)標(biāo)簽的中心點(diǎn)。一開始Agent 自信地匯報(bào)了戰(zhàn)況系統(tǒng)播報(bào)17 tabs, 1 mismatches字面意思只有 1 個(gè)報(bào)錯(cuò)其余 16 個(gè)完美通過(guò)。但僅僅四分半鐘后寫測(cè)試的 Agent 自己推翻了這行讀數(shù)真正被有效檢驗(yàn)過(guò)的只有 13 個(gè)。標(biāo)簽狀態(tài)Agent 最初匯報(bào)真實(shí)情況假警報(bào)原因第 1~13 個(gè)成功成功正常點(diǎn)擊沒(méi)問(wèn)題。第 14 個(gè)失敗成功界面太擠標(biāo)簽中心點(diǎn)被右側(cè)的「」按鈕蓋住了點(diǎn)錯(cuò)位置了。第 15~17 個(gè)成功未測(cè)試坐標(biāo)已超出屏幕邊界物理上根本點(diǎn)不到測(cè)試函數(shù)“閉眼”報(bào)了通過(guò)。為什么 15~17 號(hào)標(biāo)簽會(huì)被標(biāo)記為通過(guò)因?yàn)闇y(cè)試腳本只是去問(wèn)了代碼內(nèi)部的判定函數(shù)函數(shù)閉著眼睛回了一句ok。它看似全綠其實(shí)一個(gè)像素都沒(méi)真正測(cè)到。Agent 留言錄“報(bào)假警報(bào)的測(cè)試好歹還會(huì)讓人看一眼而報(bào)0 mismatches的測(cè)試往往是讓代碼失去信任的最快方式。”修復(fù)之后測(cè)試結(jié)果不再是非黑即白的過(guò)與不過(guò)而是變成了三個(gè)維度的真實(shí)數(shù)據(jù)17 tabs, 13 ok, 0 mismatches, 4 untested第二次「盲區(qū)」盯著一個(gè)永遠(yuǎn)不會(huì)變的像素點(diǎn)第一次是測(cè)試腳本在自欺欺人第二次則是測(cè)試標(biāo)準(zhǔn)定得極其荒謬。為了測(cè)試「窗口拉大時(shí)畫面能不能及時(shí)跟上」Agent 制定了如下判定標(biāo)準(zhǔn)擴(kuò)大窗口尺寸。檢查拉大前后窗口中心點(diǎn)的像素顏色是否發(fā)生變化。如果沒(méi)變說(shuō)明畫面跟上了。從數(shù)據(jù)上看窗口尺寸從984x631變大到了1224x751中心點(diǎn)顏色一模一樣。測(cè)試完美通過(guò)然而這個(gè)測(cè)試在 Bug 存在的情況下安然無(wú)恙地「全綠」了一整天。當(dāng)天下午換了一種測(cè)量方式后真相大白當(dāng)窗口被拉大時(shí)新增的邊緣區(qū)域全是黑屏畫面渲染其實(shí)失敗了。但因?yàn)榕f畫面一直固定在左上角無(wú)論怎么拉大原本的「中心點(diǎn)」永遠(yuǎn)都會(huì)落在舊畫面里。測(cè)試標(biāo)準(zhǔn)測(cè)量位置結(jié)果缺陷舊標(biāo)準(zhǔn) (假綠)固定的窗口「舊中心點(diǎn)」永遠(yuǎn)通過(guò)就像蒙上了眼睛去驗(yàn)證光的存在完全看不到邊緣的黑屏。新標(biāo)準(zhǔn) (真抓)算出「新露出來(lái)的邊緣區(qū)域」測(cè)新區(qū)域像素真實(shí)報(bào)錯(cuò)因?yàn)樾聟^(qū)域的像素絕對(duì)不可能來(lái)自上一幀畫面。第三次「幽靈」它之所以綠是因?yàn)楦緵](méi)觸發(fā)前兩次的測(cè)試好歹還在機(jī)器上跑了第三次在報(bào)出「全綠」的那臺(tái)機(jī)器上根本連跑都沒(méi)跑過(guò)。當(dāng)時(shí)團(tuán)隊(duì)在修一個(gè) Windows 獨(dú)有的 Bug子進(jìn)程輸出權(quán)限被 AutoRun 配置攔截。為了防止 Bug 回歸Agent 寫了一條測(cè)試讓子進(jìn)程去嘗試輸出能輸出就是ok。這條測(cè)試在 macOS 開發(fā)機(jī)上跑永遠(yuǎn)是全綠通過(guò)。提交代碼的 39 分鐘后在 Windows 真機(jī)上第一次跑直接爆紅失敗。運(yùn)行環(huán)境測(cè)試結(jié)果真實(shí)原因macOS (開發(fā)機(jī))全綠通過(guò)macOS 壓根沒(méi)有 Windows 的 AutoRun 機(jī)制這條容易報(bào)錯(cuò)的代碼路徑連碰都沒(méi)碰到。Windows (真機(jī))爆紅失敗環(huán)境觸發(fā)了攔截機(jī)制真實(shí)暴露了 Bug。Agent 留言錄“一個(gè)專門為了「看機(jī)器環(huán)境決定的 Bug」而寫的測(cè)試在原本就安全的機(jī)器上跑出來(lái)的綠什么也證明不了。”怎么知道自己在被騙三個(gè)現(xiàn)成的解法總結(jié)這幾次發(fā)現(xiàn)假測(cè)試的路徑有一件事非常顯眼沒(méi)有哪一次是通過(guò)把原來(lái)那條綠色的測(cè)試再跑一遍來(lái)發(fā)現(xiàn)問(wèn)題的。你要怎么知道一條測(cè)試是不是在騙你Agent 給出了一個(gè)極其精準(zhǔn)的判別法“不要問(wèn)『這條測(cè)試通過(guò)了嗎』。你要問(wèn)『如果被測(cè)的那個(gè)東西壞了這條測(cè)試能看得見嗎』”在當(dāng)時(shí)的開發(fā)記錄里這句話最終落地成了三個(gè)非常具體的做法可以直接抄作業(yè)1. 匯總行必須報(bào)三個(gè)數(shù)不要只報(bào)「通過(guò)」和「失敗」。沒(méi)有被觸發(fā)的代碼絕不能被藏在ok的數(shù)字里。通過(guò) (OK)不符 (Mismatch/Fail)沒(méi)測(cè)到 (Untested/Skipped)——三個(gè)數(shù)加起來(lái)必須等于總數(shù)。2. 「預(yù)期為空」的旁邊綁一條「預(yù)期非空」如果你測(cè)試的標(biāo)準(zhǔn)是“日志里沒(méi)有報(bào)錯(cuò)”這可能意味著沒(méi)報(bào)錯(cuò)但也可能意味著代碼壓根就沒(méi)運(yùn)行斷言必須有底線你可以要求沒(méi)報(bào)錯(cuò)但必須同時(shí)斷言**“程序確實(shí)執(zhí)行到了這里”**比如要求某個(gè)常規(guī)啟動(dòng)日志至少出現(xiàn)一次。如果沒(méi)有一律記作「沒(méi)測(cè)到」。3. 故意改壞代碼看測(cè)試紅不紅最硬核寫完測(cè)試后故意把被測(cè)邏輯改錯(cuò)比如把取點(diǎn)位置寫偏或者強(qiáng)行制造異常。如果代碼明明壞了測(cè)試依然是綠的說(shuō)明這個(gè)測(cè)試根本就是瞎的。每一次主動(dòng)制造的紅都是為了證明下一次的綠有意義。下次如果你的 AI Agent 瀟灑地告訴你0 failures時(shí)記得接著問(wèn)它兩個(gè)數(shù)字“跳過(guò)了幾格有幾格根本沒(méi)跑到”