測(cè)試寫成AI Skill:一句話自動(dòng)點(diǎn)完全部流程)
做前端的時(shí)間一長(zhǎng)你會(huì)發(fā)現(xiàn)最煩人的往往不是寫業(yè)務(wù)代碼而是反復(fù)去“點(diǎn)”同一個(gè)后臺(tái)頁(yè)面。尤其是控制臺(tái)類的管理系統(tǒng)菜單嵌套、權(quán)限點(diǎn)多、表單校驗(yàn)奇奇怪怪每次發(fā)版前我都要手動(dòng)把核心流程點(diǎn)一遍點(diǎn)得人只想寫個(gè)機(jī)器人替我上班。后來(lái)我把這套前端測(cè)試直接寫成了一個(gè) Skill在 AI 編程助手里掛一個(gè)自定義技能包然后我只需要輸入一句話比如“從登錄開(kāi)始把所有用戶管理的增刪改查流程全部走一遍”AI 就會(huì)自己打開(kāi)控制臺(tái)順著操作路徑點(diǎn)擊、輸入、校驗(yàn)、截圖把整個(gè)控制臺(tái)點(diǎn)完最后給我一份帶證據(jù)鏈的測(cè)試報(bào)告。這篇就聊聊我是怎么把這個(gè) Skill 做出來(lái)的包括 Skill 和普通 Prompt 的區(qū)別、控制臺(tái)測(cè)試的核心建模思路、落地步驟以及我實(shí)測(cè)中踩過(guò)的幾個(gè)坑。1. 控制臺(tái)這類頁(yè)面的測(cè)試為什么這么折磨人1.1 控制臺(tái)頁(yè)面的特性狀態(tài)多、鏈路長(zhǎng)、權(quán)限雜控制臺(tái)和普通官網(wǎng)頁(yè)面完全是兩種生物。官網(wǎng)頁(yè)面基本是“展示型”打開(kāi)就能看交互最多到表單提交。控制臺(tái)則是“操作型”每個(gè)頁(yè)面背后都是一串狀態(tài)列表篩選、彈窗新建、編輯保存、批量刪除、權(quán)限校驗(yàn)、操作日志每一步都依賴前一步的結(jié)果。最典型的就是用戶管理你要測(cè)“新建用戶”就得先準(zhǔn)備角色、分配權(quán)限、再填賬號(hào)信息測(cè)“編輯用戶”又得先有一條已存在的用戶數(shù)據(jù)測(cè)“刪除用戶”還要考慮當(dāng)前用戶是不是管理員、被刪用戶是否被其他業(yè)務(wù)引用。這些操作串起來(lái)是一條很長(zhǎng)的鏈路任何一個(gè)環(huán)節(jié)的數(shù)據(jù)缺失、權(quán)限不足、接口異常都會(huì)導(dǎo)致后面全部跑不動(dòng)。更麻煩的是權(quán)限矩陣。同一個(gè)控制臺(tái)超級(jí)管理員看到的菜單和普通操作員看到的完全不同。有些按鈕只有特定角色才顯示有些接口只有特定 IP 段才允許訪問(wèn)。手工測(cè)試還能憑“經(jīng)驗(yàn)”繞過(guò)去自動(dòng)化腳本一旦寫錯(cuò)判定條件就會(huì)在權(quán)限邊界上反復(fù)橫跳最后測(cè)出來(lái)的結(jié)果根本不能說(shuō)明問(wèn)題。1.2 傳統(tǒng)自動(dòng)化測(cè)試的“三個(gè)斷層”我最早也試過(guò)用 Playwright、Cypress 這類工具寫 E2E 腳本。剛開(kāi)始覺(jué)得挺美好真正維護(hù)起來(lái)才發(fā)現(xiàn)有三個(gè)斷層第一個(gè)斷層是選擇器不穩(wěn)定。從開(kāi)發(fā)者工具里復(fù)制出來(lái)的 CSS 路徑頁(yè)面改一次版就崩一次??刂婆_(tái)又是動(dòng)態(tài)組件重災(zāi)區(qū)表格行會(huì)復(fù)用、彈窗會(huì)重渲染、按鈕 ID 經(jīng)常帶一串隨機(jī)數(shù)。你花一下午寫好的幾十個(gè) selector可能因?yàn)榍岸思恿艘粋€(gè) loading 狀態(tài)就全部失效。第二個(gè)斷層是數(shù)據(jù)狀態(tài)不可控。測(cè)試腳本跑在最理想的數(shù)據(jù)假設(shè)上環(huán)境里恰好有一條叫“test_user”的數(shù)據(jù)、恰好沒(méi)有臟數(shù)據(jù)擋住彈窗。但實(shí)際上控制臺(tái)測(cè)試環(huán)境往往是共用的你上一條用例產(chǎn)生的數(shù)據(jù)可能就污染了下一條用例的判定。要解決就得做數(shù)據(jù)初始化、接口 Mock、數(shù)據(jù)庫(kù)清理工作量比寫腳本本身還大。第三個(gè)斷層是斷言成本高。前端頁(yè)面大多是異步渲染你點(diǎn)完保存到底什么時(shí)候該斷言“成功提示”sleep 3 秒太蠢等待某個(gè)接口返回又需要額外封裝。更別說(shuō)控制臺(tái)里有大量表格、圖表、狀態(tài)流轉(zhuǎn)斷言邏輯寫得稍微粗一點(diǎn)就會(huì)出現(xiàn)“測(cè)試全綠但功能實(shí)際上已經(jīng)壞了”的假陽(yáng)性。這三個(gè)斷層疊加起來(lái)最終的結(jié)果就是自動(dòng)化測(cè)試腳本變成了團(tuán)隊(duì)里的“擺設(shè)”平時(shí)不敢跑發(fā)版前才跑一次跑掛了也沒(méi)人愿意去修。這不是工具的問(wèn)題而是我們一直在用“固定路徑腳本”去對(duì)抗“高度動(dòng)態(tài)頁(yè)面”路徑一斷整個(gè)測(cè)試就塌了。2. Skill 與傳統(tǒng) Prompt/腳本的根本區(qū)別2.1 Skill 是一套“可復(fù)用的任務(wù)能力包”很多朋友一聽(tīng)到“把前端測(cè)試寫成 Skill”第一反應(yīng)是這不就是寫一個(gè)Prompt嗎讓 AI 去點(diǎn)擊頁(yè)面然后我再補(bǔ)一句“小心點(diǎn)別點(diǎn)錯(cuò)了”就行了。但真正的 Skill 不是一句話而是一整套結(jié)構(gòu)化的技能包。你可以把它理解成給實(shí)習(xí)生一本工作手冊(cè)而不是在口頭交代任務(wù)。手冊(cè)里寫清楚了這個(gè)崗位負(fù)責(zé)什么、有哪些操作規(guī)范、遇到異常怎么處理、哪些事情絕對(duì)禁止。而 Prompt 只是你臨時(shí)說(shuō)的一句“幫我去把用戶管理測(cè)一下”AI 可能理解成“用接口測(cè)”也可能理解成“用瀏覽器測(cè)”完全看運(yùn)氣。我用的這套 Skill 目錄大概長(zhǎng)這樣skill-frontend-console-test/ ├── SKILL.md ├── commands/ │ ├── login.md │ ├── navigate.md │ └── assert.md ├── pages/ │ ├── login.md │ ├── user-list.md │ └── role-manage.md ├── workflows/ │ └── smoke-test.md └── examples/ └── user-crud.mdSKILL.md 是入口文件定義了技能的名稱、用途、觸發(fā)條件、操作邊界commands 里是 AI 可以使用的原子動(dòng)作比如登錄、跳轉(zhuǎn)、斷言pages 里是控制臺(tái)每個(gè)頁(yè)面的關(guān)鍵元素和可用操作workflows 里是常用業(yè)務(wù)流程的串聯(lián)方式examples 里放幾個(gè)經(jīng)典的執(zhí)行樣例。當(dāng) AI 加載這個(gè) Skill 時(shí)它看到的不是散落的指令而是一個(gè)“完整的工作環(huán)境”。它知道自己在測(cè)試控制臺(tái)知道每個(gè)頁(yè)面長(zhǎng)什么樣知道每個(gè)流程應(yīng)該按什么順序走知道哪些按鈕危險(xiǎn)不能隨便點(diǎn)。這才叫把前端測(cè)試寫成了 Skill而不是寫了個(gè)花哨的提示詞。2.2 為什么一句話能驅(qū)動(dòng)它為什么我只需要輸入“從登錄開(kāi)始把用戶管理流程走一遍”AI 就能自動(dòng)跑完整條鏈路因?yàn)樗x完 Skill 之后已經(jīng)把這句話拆成了“登錄→進(jìn)入用戶管理→新建→編輯→刪除→退出登錄”這樣的任務(wù)列表然后從 pages 和 workflows 里找到了每一步對(duì)應(yīng)的操作描述再調(diào)用 commands 里的原語(yǔ)去實(shí)際執(zhí)行。這本質(zhì)上是一個(gè)“意圖識(shí)別 路徑規(guī)劃 原語(yǔ)執(zhí)行”的過(guò)程。用戶的一句話是意圖Skill 里的 workflows 是路徑commands 和 pages 是執(zhí)行細(xì)節(jié)。沒(méi)有 Skill 的時(shí)候AI 只能靠猜有了 SkillAI 是在“照章辦事”。所以“一句話點(diǎn)完整個(gè)控制臺(tái)”并不是魔法而是我把原本需要在測(cè)試文檔里寫幾千字的操作步驟提前結(jié)構(gòu)化地塞進(jìn)了 Skill。AI 只是那個(gè)替我照著文檔執(zhí)行的人。2.3 和傳統(tǒng) E2E 腳本的本質(zhì)區(qū)別為了說(shuō)清楚這件事我列了一個(gè)對(duì)比表格你可以直觀感受一下差異對(duì)比維度傳統(tǒng) E2E 腳本Skill 化的 AI 測(cè)試執(zhí)行方式固定代碼路徑一步不能錯(cuò)意圖驅(qū)動(dòng)AI 自動(dòng)規(guī)劃路徑頁(yè)面變更手動(dòng)改 selector 和流程代碼改 pages/workflows 里的語(yǔ)義描述異常處理腳本遇到異常就退出AI 能讀頁(yè)面、截圖、自糾錯(cuò)斷言策略硬編碼的 expect結(jié)合頁(yè)面狀態(tài)機(jī)和預(yù)期反饋動(dòng)態(tài)校驗(yàn)維護(hù)成本每次需求變更都要改代碼主要是補(bǔ)充語(yǔ)義描述和示例可解釋性失敗日志是堆棧輸出帶截圖的完整操作理由傳統(tǒng)腳本像是在鐵軌上跑火車鐵軌鋪到哪火車就只能跑到哪。軌道一斷火車就趴窩。Skill 化的 AI 測(cè)試更像一個(gè)會(huì)看地圖的司機(jī)你告訴他目的地他自己找路、自己避坑、自己確認(rèn)有沒(méi)有到。我不否認(rèn)傳統(tǒng) E2E 的價(jià)值但面對(duì)控制臺(tái)這種高動(dòng)態(tài)、多狀態(tài)、長(zhǎng)鏈路的場(chǎng)景傳統(tǒng)腳本的維護(hù)成本實(shí)在太高了。Skill 的思路不是徹底取代腳本而是把“怎么寫腳本”這個(gè)問(wèn)題變成了“怎么描述頁(yè)面和流程”而 AI 最擅長(zhǎng)的恰恰就是理解描述。3. 把前端測(cè)試裝進(jìn) Skill 的核心設(shè)計(jì)3.1 先給控制臺(tái)畫一張“操作地圖”做 Skill 之前我做的第一件事不是寫代碼而是把控制臺(tái)的每個(gè)頁(yè)面都梳理成一張“操作地圖”。這張地圖不需要精確到 CSS 選擇器但必須把語(yǔ)義信息寫清楚這個(gè)頁(yè)面有哪些功能按鈕、每個(gè)按鈕點(diǎn)了之后預(yù)期出現(xiàn)什么反饋、當(dāng)前頁(yè)面從哪里可以跳轉(zhuǎn)到哪里。我以用戶管理模塊為例建了這樣一張表頁(yè)面可用動(dòng)作關(guān)鍵元素預(yù)期反饋登錄頁(yè)輸入賬號(hào)密碼、點(diǎn)擊登錄用戶名輸入框、密碼輸入框、登錄按鈕跳轉(zhuǎn)首頁(yè)右上角出現(xiàn)用戶頭像用戶列表搜索、新建、行內(nèi)編輯、刪除搜索框、新建用戶按鈕、表格行、操作列列表刷新、彈窗打開(kāi)、出現(xiàn)操作成功提示新建用戶彈窗填寫表單、保存、取消姓名輸入框、手機(jī)號(hào)輸入框、角色下拉框、保存按鈕彈窗關(guān)閉列表出現(xiàn)新用戶接口調(diào)用成功角色管理創(chuàng)建角色、分配權(quán)限角色名稱輸入框、權(quán)限樹(shù)、保存按鈕角色列表更新權(quán)限勾選被保存我把這些信息寫進(jìn) pages 目錄下的對(duì)應(yīng)文件里。注意我沒(méi)有用“#user-list .edit-btn”這種選擇器而是寫“用戶列表行右側(cè)的編輯按鈕”。因?yàn)?AI 在處理這種語(yǔ)義描述時(shí)會(huì)比處理一串隨機(jī)生成的 class 名穩(wěn)定得多。這算是整份 Skill 能跑通的一個(gè)關(guān)鍵設(shè)計(jì)原則用人的語(yǔ)言描述頁(yè)面而不是用機(jī)器的語(yǔ)言。3.2 把自然語(yǔ)言指令翻譯成可執(zhí)行動(dòng)作有了操作地圖接下來(lái)要定義一層“可執(zhí)行動(dòng)作原語(yǔ)”。這層原語(yǔ)相當(dāng)于 AI 的手和腳每個(gè)動(dòng)作都要有明確的輸入、輸出和失敗條件。我在 Skill 的 commands 目錄里定義了一組基礎(chǔ)動(dòng)作open(url)打開(kāi)目標(biāo)環(huán)境地址login(user, password)執(zhí)行登錄流程navigate(頁(yè)面描述)通過(guò)菜單或路由跳轉(zhuǎn)到指定頁(yè)面click(元素描述)點(diǎn)擊頁(yè)面上某個(gè)語(yǔ)義元素fill(元素描述, 值)在輸入框填入內(nèi)容wait_until(狀態(tài)描述)等待某個(gè)預(yù)期狀態(tài)出現(xiàn)比如“表格加載完成”assert_visible(元素描述)斷言某個(gè)元素可見(jiàn)assert_text(元素描述, 預(yù)期文本)斷言某個(gè)元素包含預(yù)期文本screenshot(名稱)給當(dāng)前狀態(tài)截圖留證當(dāng) AI 接到“測(cè)試新建用戶功能”這個(gè)指令時(shí)它會(huì)根據(jù) workflows 文件里的定義生成類似下面這樣的動(dòng)作序列navigate(用戶管理) wait_until(用戶列表已加載) click(新建用戶按鈕) wait_until(新建用戶彈窗已打開(kāi)) fill(姓名輸入框, test_user_01) fill(手機(jī)號(hào)輸入框, 13800138000) click(保存按鈕) assert_visible(操作成功提示) screenshot(新建用戶完成)這些動(dòng)作看起來(lái)很像傳統(tǒng)測(cè)試腳本但區(qū)別在于每一個(gè)動(dòng)作里的“元素描述”都是語(yǔ)義化的。AI 會(huì)在執(zhí)行時(shí)自己去頁(yè)面上尋找匹配的按鈕、輸入框、彈窗而不是依賴一個(gè)寫死的 selector。所以哪怕前端微調(diào)了布局只要文案和層級(jí)沒(méi)有大變這個(gè)序列大概率還是能跑通。3.3 測(cè)試斷言與 UI 狀態(tài)機(jī)的結(jié)合控制臺(tái)測(cè)試最容易忽略的一點(diǎn)是頁(yè)面是有狀態(tài)的斷言必須跟著狀態(tài)走。我用了一個(gè)很樸素的狀態(tài)機(jī)思路每個(gè)頁(yè)面定義“前置狀態(tài)”和“后置狀態(tài)”。點(diǎn)擊“保存”之前表單處于“可編輯狀態(tài)”點(diǎn)擊保存之后預(yù)期狀態(tài)應(yīng)該是“彈窗關(guān)閉、列表刷新、出現(xiàn)成功提示”。AI 每執(zhí)行完一個(gè)動(dòng)作都要用wait_until和assert_visible去校驗(yàn)狀態(tài)是否如期遷移。如果狀態(tài)沒(méi)有遷移比如點(diǎn)擊保存后彈窗沒(méi)關(guān)、列表沒(méi)刷新AI 就要啟動(dòng)“自我修正”流程先截圖、讀取當(dāng)前頁(yè)面文本、對(duì)比預(yù)期再?zèng)Q定是重試一次還是調(diào)整操作。這一步是整個(gè) Skill 里最重要的設(shè)計(jì)。因?yàn)闆](méi)有斷言的“點(diǎn)完”只是走馬觀花只有把狀態(tài)校驗(yàn)也包進(jìn)去測(cè)試才算真正有說(shuō)服力。4. 從零到一落地這個(gè) Skill 的關(guān)鍵步驟4.1 搭建 Skill 骨架定義邊界和授權(quán)任何 AI 編程助手里的 Skill第一步都是把目錄結(jié)構(gòu)和入口文件搭起來(lái)。別急著寫 pages 和 workflows先把“這個(gè)技能能干什么、不能干什么”說(shuō)清楚。我在 SKILL.md 開(kāi)頭寫了這樣一段元信息--- name: frontend-console-test description: 用于Web控制臺(tái)的前端自動(dòng)化測(cè)試根據(jù)自然語(yǔ)言指令執(zhí)行點(diǎn)擊流程并輸出報(bào)告 allowed_operations: [open, navigate, click, fill, wait_until, assert, screenshot] forbidden_operations: [delete_without_confirm, export_without_confirm] ---這段信息的作用是給 AI 一個(gè)“行為紅線”??刂婆_(tái)里有很多高危操作刪除數(shù)據(jù)、批量導(dǎo)出、修改權(quán)限這些動(dòng)作一旦誤觸代價(jià)非常大。所以我明確告訴 AI刪除和導(dǎo)出這類操作如果沒(méi)有在指令里顯式說(shuō)明并且經(jīng)過(guò)我的二次確認(rèn)一律禁止執(zhí)行。各家 AI 助手的 Skill 格式可能會(huì)有一點(diǎn)差別但核心思想是通用的你給出的邊界越清楚AI 就越不會(huì)自作主張。很多人在這個(gè)環(huán)節(jié)偷懶結(jié)果后面 AI “發(fā)揮想象力”點(diǎn)了一堆不該點(diǎn)的按鈕這不是 AI 的錯(cuò)是你沒(méi)教好。4.2 在真實(shí)控制臺(tái)上跑通第一個(gè)用例骨架搭好之后我沒(méi)有急著寫全量頁(yè)面而是先挑最簡(jiǎn)單的“登錄→進(jìn)入用戶管理→退出”跑通。這個(gè)過(guò)程其實(shí)是一場(chǎng)“調(diào)教”我打開(kāi)真實(shí)控制臺(tái)讓 AI 開(kāi)始執(zhí)行。我輸入“登錄測(cè)試賬號(hào)進(jìn)入用戶管理截圖當(dāng)前頁(yè)面”。然后盯著 AI 的行為序列看注意它是不是先打開(kāi)了地址、再填賬號(hào)密碼、點(diǎn)擊登錄、等待跳轉(zhuǎn)最后才截圖。如果 AI 點(diǎn)了錯(cuò)誤的按鈕或者跳過(guò)了等待步驟我不會(huì)直接說(shuō)“重新來(lái)一次”而是回到 pages 文件里修正對(duì)應(yīng)的語(yǔ)義描述。比如它總是找不到“登錄按鈕”我就把元素描述改得更具體一點(diǎn)“登錄按鈕是頁(yè)面右下角藍(lán)色的圓角按鈕”。重復(fù)幾輪之后AI 的行為會(huì)越來(lái)越穩(wěn)定這就是讓 Skill 真正學(xué)會(huì)“你的控制臺(tái)長(zhǎng)什么樣”的過(guò)程。4.3 從單條指令擴(kuò)展到全控制臺(tái)巡檢第一個(gè)用例跑通后后面的擴(kuò)展其實(shí)就是復(fù)制粘貼加調(diào)整。我把日常手工測(cè)試的高頻流程全部寫成了 workflows用戶管理、角色權(quán)限、訂單審批、數(shù)據(jù)導(dǎo)入、配置發(fā)布每個(gè)流程鏈都包括前置條件、操作步驟、預(yù)期結(jié)果和后置清理。然后我再定義了一個(gè)復(fù)合任務(wù)叫“全控制臺(tái)巡檢”依次執(zhí)行所有 workflows每個(gè)流程結(jié)束都截圖并記錄結(jié)果。這樣我每天早上只需要對(duì) AI 說(shuō)一句“執(zhí)行全控制臺(tái)巡檢”它就會(huì)自己跑完所有核心鏈路再輸出一份 Markdown 報(bào)告里面包含每個(gè)流程的通過(guò)/失敗狀態(tài)、關(guān)鍵操作截圖、失敗原因分析。實(shí)測(cè)下來(lái)一次巡檢大概能覆蓋我平時(shí)手動(dòng)測(cè)試 40 分鐘的內(nèi)容AI 最快五分鐘內(nèi)就能跑完。當(dāng)然個(gè)別流程因?yàn)閿?shù)據(jù)準(zhǔn)備原因偶爾會(huì)失敗但 AI 會(huì)把失敗原因?qū)懙妹髅靼装孜抑恍枰磮?bào)告決定是修腳本還是修數(shù)據(jù)。5. 跑通之后我踩過(guò)的那些坑5.1 選擇器不是唯一解語(yǔ)義、角色、坐標(biāo)最開(kāi)始我犯了一個(gè)非常經(jīng)典的錯(cuò)誤為了讓 AI 定位準(zhǔn)確我在 pages 里塞了大量 CSS 選擇器。結(jié)果頁(yè)面一改版選擇器失效AI 直接抓瞎。后來(lái)我改成“語(yǔ)義定位優(yōu)先”優(yōu)先用頁(yè)面上可見(jiàn)的按鈕文字、菜單名稱、表單 label 來(lái)定位。比如“點(diǎn)擊用戶列表右側(cè)操作列的編輯按鈕”而不是“點(diǎn)擊 #edit-3”。你會(huì)發(fā)現(xiàn) AI 對(duì)這種描述的理解能力遠(yuǎn)超預(yù)期因?yàn)樗谔幚頃r(shí)不只是讀 DOM還會(huì)結(jié)合可訪問(wèn)性樹(shù)和視覺(jué)信息。如果元素沒(méi)有清晰的文字標(biāo)簽?zāi)蔷徒o它加一個(gè)語(yǔ)義別名。比如“保存按鈕”可能頁(yè)面上有多個(gè)我會(huì)寫成“新建用戶彈窗右下角的保存按鈕”。用坐標(biāo)定位是最不得已的方案我?guī)缀醪挥靡驗(yàn)榭刂婆_(tái)是響應(yīng)式布局坐標(biāo)在不同視口下完全不一樣。5.2 AI 操作過(guò)快導(dǎo)致?tīng)顟B(tài)不同步第二個(gè)坑是 AI 的手速太快了。它剛點(diǎn)完“進(jìn)入用戶管理”下一秒就要去點(diǎn)“新建用戶按鈕”但這時(shí)候表格還在加載按鈕還沒(méi)渲染出來(lái)結(jié)果就撲了個(gè)空。解決方案不是加 sleep而是在 Skill 里強(qiáng)制約定每個(gè)動(dòng)作執(zhí)行完之后必須先wait_until等預(yù)期狀態(tài)出現(xiàn)再執(zhí)行下一步。等什么等接口返回后頁(yè)面出現(xiàn)的確定信號(hào)比如“用戶列表已加載”或“彈窗已打開(kāi)”。這個(gè)約定看起來(lái)讓流程變慢了但換來(lái)的是整體成功率的大幅提升。我還給 AI 加了“單步確認(rèn)”模式。最開(kāi)始調(diào)試 Skill 時(shí)每一步都會(huì)輸出當(dāng)前操作和當(dāng)前頁(yè)面狀態(tài)方便我看它有沒(méi)有按預(yù)期走。跑穩(wěn)定之后再關(guān)掉確認(rèn)讓它自動(dòng)連續(xù)執(zhí)行。5.3 斷言失敗時(shí)讓 AI 自己“糾錯(cuò)”第一版 Skill 遇到斷言失敗就直接停。后來(lái)我加了一個(gè)“自糾錯(cuò)循環(huán)”斷言失敗之后AI 先截圖并讀取當(dāng)前頁(yè)面文本把“預(yù)期”和“實(shí)際”做一個(gè)對(duì)比然后分兩種情況處理。如果是頁(yè)面元素描述過(guò)時(shí)了它就去更新 pages 里的語(yǔ)義描述然后重新執(zhí)行這一步。比如我寫過(guò)“保存成功提示”但前端后來(lái)改成了“操作成功”斷言失敗后 AI 發(fā)現(xiàn)文案變了會(huì)把這個(gè)文案更新為兩種都可接受并在最終報(bào)告里標(biāo)注“頁(yè)面文案發(fā)生變更”。如果是真正的功能 BugAI 會(huì)把這個(gè)失敗原樣記錄到報(bào)告里標(biāo)紅不會(huì)擅自修改斷言去“掩蓋問(wèn)題”。這個(gè)機(jī)制非常關(guān)鍵因?yàn)樗谋举|(zhì)是讓測(cè)試腳本自己進(jìn)化而不是每次前端一改版就需要人工去維護(hù)斷言。5.4 權(quán)限與安全邊界是必須提前設(shè)好的我剛做完 Skill 的時(shí)候很興奮有一次讓 AI“把控制臺(tái)所有按鈕點(diǎn)一遍”結(jié)果它真的差點(diǎn)去執(zhí)行一個(gè)生產(chǎn)環(huán)境的數(shù)據(jù)清理任務(wù)。雖然我的 Skill 前綴帶了forbidden_operations但那次我用的指令是“所有按鈕”繞過(guò)了具體限制。這件事之后我把安全邏輯做了兩層加固第一層Skill 只允許在指定測(cè)試域名下工作非測(cè)試環(huán)境直接拒絕執(zhí)行第二層凡是涉及刪除、導(dǎo)出、修改權(quán)限這類高危動(dòng)作AI 必須先暫停并問(wèn)我“是否確認(rèn)執(zhí)行”我不確認(rèn)就不動(dòng)。永遠(yuǎn)不要假設(shè) AI 有“常識(shí)”。在 Skill 里把邊界寫到足夠死才是負(fù)責(zé)任的用法??刂婆_(tái)測(cè)試的終極目標(biāo)不是讓 AI 替我亂點(diǎn)而是讓 AI 在一個(gè)受控的范圍內(nèi)幫我做重復(fù)勞動(dòng)。6. 這個(gè) Skill 帶來(lái)的延伸價(jià)值和個(gè)人體會(huì)做完這個(gè) Skill 之后我發(fā)現(xiàn)它最大的收獲其實(shí)不是“省了幾個(gè)小時(shí)手點(diǎn)”而是讓我重新理解了前端測(cè)試這件事。以前寫測(cè)試用例最后沉淀下來(lái)的是幾百行代碼和一群沒(méi)人看的文檔?,F(xiàn)在這些知識(shí)全部變成 Skill 里的語(yǔ)義描述和 workflow每次頁(yè)面改版我更新 pages 文件的過(guò)程本質(zhì)上就是在整理“當(dāng)前控制臺(tái)到底長(zhǎng)什么樣”。這份活文檔對(duì)團(tuán)隊(duì)新人也特別友好新同學(xué)想了解控制臺(tái)的核心流程不用再看幾十頁(yè) case直接讓 AI 跑一遍巡檢再看報(bào)告就能理解七七八八。另外AI 在點(diǎn)擊過(guò)程中還會(huì)“順便”發(fā)現(xiàn)一些可訪問(wèn)性問(wèn)題。比如某個(gè)按鈕沒(méi)有可訪問(wèn)性標(biāo)簽AI 定位時(shí)會(huì)猶豫很久某個(gè)頁(yè)面打開(kāi)后焦點(diǎn)沒(méi)有落在預(yù)期位置AI 會(huì)把它記成一條體驗(yàn)問(wèn)題。這些都是以前寫自動(dòng)化測(cè)試腳本時(shí)根本不會(huì)留意到的細(xì)節(jié)但恰恰是控制臺(tái)這類后臺(tái)系統(tǒng)日常最容易忽略的質(zhì)量問(wèn)題。如果讓我重新做一次我會(huì)更早放棄“寫死腳本”的執(zhí)念直接從語(yǔ)義描述和狀態(tài)機(jī)入手。給 AI 一本好的工作手冊(cè)比教它一萬(wàn)句臨場(chǎng)指令管用得多。而且別指望第一天就能“一句話點(diǎn)完全部”先把最高頻的一條流程做到百分百穩(wěn)定再一點(diǎn)點(diǎn)把整個(gè)控制臺(tái)裝進(jìn) Skill 里。這個(gè)不斷沉淀的過(guò)程才是這類 AI 測(cè)試方案真正值得投入的地方。