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