:自然語言驅(qū)動UI自動化測試)
上周我被測試群里一張截圖弄得有點沮喪。一條跑了三年的核心下單鏈路用例因為前端把登錄按鈕的id從login-btn改成submit-login一夜間紅了 26 條。新同事說改選擇器就能解決但沒有人知道這個按鈕在第三個版本里還會不會再改一次。這種時刻我意識到傳統(tǒng) UI 自動化最貴的成本不是寫用例而是維護用例。于是我開始認真看 midscene 這個方向一個用自然語言驅(qū)動瀏覽器、讓 AI 智能體自己看頁面、做操作、驗結(jié)果的框架。這篇文章我會把 midscene 智能體做 AI 自動化測試的環(huán)境搭建、Demo 演示完整展開也會把midscene 被 Playwright 調(diào)用的原理這一部分講透。我不打算只給命令還會解釋每一步為什么這么做、實測中會遇到哪些坑、怎么排錯。適合正在評估 AI Agent 做 Web 自動化測試的團隊也適合想親手跑通第一個 AI 測試 Demo 的個人開發(fā)者。不管你之前用的是 Selenium、Playwright 還是 Appium這篇文章的思路都能接上。1. 傳統(tǒng)UI自動化的脆弱性與midscene智能體的解題思路1.1 一次前端改版引發(fā)的用例雪崩先還原一下開頭那個場景。老用例長這樣// 用了三年突然紅了 await page.click(#login-btn);前端把按鈕id改成>mkdir midscene-demo cd midscene-demo npm init -y npm i -D midscene/web playwright typescript tsx npx playwright install chromium每一步我都解釋一下為什么這么做npm init -y生成一個默認的package.json給項目一個包管理入口。npm i -D midscene/web playwright typescript tsx一次裝齊四個依賴。midscene/web是智能體 SDKplaywright是瀏覽器自動化框架typescript用來寫 TS 腳本tsx是一個可以直接運行 TypeScript 文件的工具省去單獨的編譯步驟。npx playwright install chromium下載 Chromium 瀏覽器內(nèi)核。這一步特別容易被人跳過因為剛才明明按了 playwright怎么跑不起來原因很簡單playwright 的 npm 包只是客戶端瀏覽器內(nèi)核需要單獨下載。如果下載超時先檢查本機網(wǎng)絡能否正常訪問外部網(wǎng)絡和 DNS 解析不要跳過這步后面所有腳本都依賴這個瀏覽器內(nèi)核。3.3 模型參數(shù)的環(huán)境變量配置先把模型的三個環(huán)境變量配好export AI_API_KEY你的模型服務密鑰 export AI_BASE_URL你的模型服務商兼容接口地址 export AI_MODELgpt-4o 或 qwen-vl 等同類型支持視覺的模型ID這里有一個很關鍵的實踐絕對不要把密鑰寫死在代碼里。一方面測試腳本經(jīng)常會提交到倉庫里密鑰一旦提交就等于泄露另一方面CI 環(huán)境里換模型只需要改環(huán)境變量不需要動代碼。團隊內(nèi)部如果統(tǒng)一走模型網(wǎng)關也可以把AI_BASE_URL指向網(wǎng)關地址方便統(tǒng)一計費和審計。配完之后可以用下面的命令驗證一下環(huán)境變量是否已經(jīng)生效echo $AI_API_KEY如果輸出為空說明當前終端會話沒有拿到變量檢查一下是否用了錯誤的變量名。3.4 用最小腳本驗證智能體真的能操作頁面環(huán)境裝好之后寫一個最小的驗證腳本業(yè)務邏輯越簡單越好避免把問題混在一起。新建first-run.tsimport { chromium } from playwright; import { PlaywrightAgent } from midscene/web; async function main() { const browser await chromium.launch({ headless: false }); const page await browser.newPage(); const agent new PlaywrightAgent(page); await page.goto(https://www.saucedemo.com/); await agent.runTask(在用戶名輸入框填入 standard_user在密碼輸入框填入 secret_sauce); await agent.runTask(點擊 LOGIN 按鈕并斷言頁面出現(xiàn) Products 標題); await browser.close(); } main();運行npx tsx first-run.ts如果你裝到的 midscene 版本入口路徑不同比如midscene/web/playwright下導出以你裝到的版本提示為準核心用法不變創(chuàng)建PlaywrightAgent傳入 Playwright 的page對象然后runTask下指令。跑起來之后你會看到瀏覽器窗口自己打開自動填入賬號密碼點擊登錄然后進入商品列表頁。這一步跑通說明你的環(huán)境基本沒問題。4. 可復現(xiàn)的Demo自然語言驅(qū)動登錄與自動驗證4.1 目標場景選型為什么選一個公開練習站選場景是有講究的。第一次跑 AI 智能體千萬不要拿公司內(nèi)部復雜的后臺系統(tǒng)練手因為任何一個環(huán)境變量、權(quán)限、彈窗問題都會讓你分不清是環(huán)境問題還是智能體問題。我推薦用 SauceDemo 這個公開練習站。它專門為自動化測試設計登錄賬號固定、商品列表穩(wěn)定、購物車流程完整頁面結(jié)構(gòu)也不復雜非常適合驗證AI 智能體到底能不能看懂頁面并執(zhí)行流程。場景設計如下打開 SauceDemo 首頁。用 standard_user 登錄。進入商品詳情頁把 Sauce Labs Backpack 加入購物車。進入購物車頁面斷言商品存在并取回價格。這個流程覆蓋了輸入、點擊、跳轉(zhuǎn)、斷言、數(shù)據(jù)提取幾個核心能力足夠說明問題。4.2 完整Demo腳本登錄、斷言、再到加購新建demo-flow.tsimport { chromium } from playwright; import { PlaywrightAgent } from midscene/web; async function main() { const browser await chromium.launch({ headless: false }); const page await browser.newPage(); const agent new PlaywrightAgent(page); await page.goto(https://www.saucedemo.com/); await agent.runTask(完成登錄使用 standard_user 登錄密碼 secret_sauce然后點擊登錄按鈕); await agent.runTask(在商品列表中點擊名稱為 Sauce Labs Backpack 的商品圖片進入詳情頁); await agent.runTask(點擊 Add to cart 按鈕然后點擊購物車圖標); await agent.runTask(斷言購物車頁面里商品名包含 Sauce Labs Backpack并輸出商品價格); await browser.close(); } main();這里四個runTask分別對應四段意圖。你會發(fā)現(xiàn)整個腳本里沒有任何一個 XPath 或 CSS 選擇器。所有定位工作全部交給智能體完成。4.3 運行鏈路解讀規(guī)劃日志、執(zhí)行日志與截圖痕跡跑這個腳本的時候控制臺會輸出類似下面的信息模型當前認為頁面處于什么狀態(tài)、計劃執(zhí)行哪些動作、動作用了什么參數(shù)、執(zhí)行結(jié)果如何。建議你在跑的時候打開兩個終端一個跑腳本一個觀察運行目錄。我實測中的輸出節(jié)奏大致是模型收到任務完成登錄先觀察頁面截圖。模型產(chǎn)生規(guī)劃第一步定位用戶名輸入框第二步定位密碼框第三步定位登錄按鈕。Playwright 依次執(zhí)行點擊、填入、再點擊。模型再次截圖確認頁面已經(jīng)跳轉(zhuǎn)到商品列表頁任務完成。注意這個 Demo 跑通后項目目錄里往往會生成報告或截圖文件。這些痕跡文件是調(diào)試的關鍵如果某一步出了問題你可以打開當時的截圖看模型眼中的頁面和你眼中的頁面是否一致。很多時候你以為頁面長這樣其實彈窗、蒙層、加載態(tài)把關鍵元素擋住了。4.4 斷言失敗時智能體的自主容錯行為傳統(tǒng)自動化里斷言失敗就是用例失敗紅色一片。midscene 的機制不太一樣runTask里的斷言更像一個目標校驗步驟。如果第一次斷言失敗智能體不會直接放棄它會重新截圖、重新思考嘗試修正操作。舉個實際例子如果登錄按鈕被一個彈窗遮住了傳統(tǒng)腳本會直接超時報錯。midscene 智能體則會先看到有個彈窗然后判斷這個彈窗是否需要關閉再執(zhí)行關閉動作最后繼續(xù)登錄。我把這個特性叫做智能體自愈。它非常像真人測試員的工作方式第一次沒找到按鈕先看看是不是被什么擋住了處理完障礙再試一次。這也是它解決UI 自動化脆弱性的核心價值——不是消除錯誤而是在出錯時有能力自己糾偏。當然自愈不是萬能的。如果一個元素壓根不存在或者頁面直接白屏模型重試幾次仍然會失敗。所以后面要講重試策略和失敗現(xiàn)場保護。5. 接進現(xiàn)有測試體系與pytest、Appium、接口自動化共存5.1 不推翻pytest讓智能體管看得見的流程我見過不少團隊聊 AI 自動化測試第一反應是是不是要把現(xiàn)有的 pytest 框架全換掉完全沒必要也不應該。pytest 這類框架最擅長的東西測試編排、數(shù)據(jù)斷言、fixture 管理、報告輸出、CI 集成。這些能力 midscene 替代不了也不應該替代。midscene 最擅長的東西是看得見的 UI 流程。所以合理的架構(gòu)是分層協(xié)作pytest 負責調(diào)度和斷言整個測試報告、執(zhí)行順序、數(shù)據(jù)準備、接口校驗仍然歸 pytest 管理。midscene 負責走流程把需要真實瀏覽器操作的步驟封裝成智能體腳本。最后的 UI 結(jié)果可以由 midscene 斷言也可以由 pytest 再做一輪兜底校驗。這樣做的好處是團隊不需要推翻現(xiàn)有的 CI 流水線和測試資產(chǎn)只是新增一種用 AI 智能體執(zhí)行 UI 流程的能力。5.2 pytest側(cè)封裝輕量入口的示例先寫一個可復用的 midscene 流程腳本比如scripts/midscene_flow.ts它能退出碼表示成功或失敗。然后 pytest 里用 subprocess 調(diào)用它import subprocess def test_saucedemo_login_flow(): result subprocess.run( [npx, tsx, scripts/midscene_flow.ts], capture_outputTrue, textTrue, ) assert result.returncode 0, result.stdout result.stderr這種方式最粗暴但也最穩(wěn)pytest 把 midscene 腳本當黑盒只需要知道流程走沒走通。如果團隊要求更精細的控制可以把 midscene 的斷言結(jié)果輸出成 JSONpytest 讀取 JSON 里返回的數(shù)據(jù)比如商品價格再做數(shù)值斷言。這里有個很重要的思路UI 流程交給 AI數(shù)據(jù)斷言回到傳統(tǒng)框架。AI 負責找到那個按鈕并點下去傳統(tǒng)斷言負責價格算得對不對。各干各最擅長的事整體穩(wěn)定性才會高。5.3 移動端Appium場景先分清WebView與原生控件聊到 Appium這里要潑一點冷水midscene 這類視覺智能體在移動端 WebView 或 H5 頁面可以用但原生控件的場景不算順暢。原因很簡單原生控件不在網(wǎng)頁 DOM 里Playwright 管不到智能體的視覺截圖與原生控件沒有直接的映射通道。如果你當前團隊以 Appium 做移動端自動化建議這樣考慮純原生頁面繼續(xù)用 Appium但可以把 AI 用在語義化斷言上。比如 Appium 取到頁面源碼和控件樹之后喂給大模型做意圖判斷這個頁面是否是登錄成功后的首頁。WebView / H5 頁面如果應用的業(yè)務頁面對應的是 H5可以考慮讓 midscene 接管瀏覽器上下文用視覺方案跑 WebView 內(nèi)的流程。混合場景先用 Appium 切到正確的 WebView context再把頁面交給 Playwright 控制最后 midscene 接管操作。移動端這塊建議先做小范圍驗證不要一上來就把核心 Appium 資產(chǎn)遷移過來。等 WebView 場景跑穩(wěn)了再逐步擴展。5.4 漸進式遷移路徑與試點范圍從一個真實案例說起。我自己的團隊做了一次小的漸進式試點只用了兩個星期效果就出來了選一條最痛的鏈路從現(xiàn)有的幾百條用例里挑出一條每次發(fā)版必做、每次改版必紅的鏈路比如創(chuàng)建訂單-提交-付款-回顯。用 midscene 重寫這條鏈路把原來的 XPath 全刪掉改成自然語言任務。并行跑一周舊的用例繼續(xù)在 CI 里跑midscene 腳本也跑對比兩者的穩(wěn)定性、失敗率、維護時間。穩(wěn)定后替換新腳本連續(xù)一周穩(wěn)定后把舊腳本下線CI 里只留智能體版本。這個過程不要心急。一次遷移太多鏈路你會獲得一堆 AI 生成的失敗報告和燒掉的 token。從一條鏈路開始拿到信心和排錯經(jīng)驗后再擴展。6. 實測中的坑、排錯清單與一條判斷標準6.1 從運行日志出發(fā)的完整排查鏈路智能體腳本報錯之后第一反應不要改代碼先看日志出現(xiàn)在哪一層。我按實際經(jīng)驗整理了這樣一個排查順序環(huán)境變量層是否報401或missing api key 大概率是AI_API_KEY沒設置或設置錯誤。模型調(diào)用層是否返回空結(jié)果、JSON 解析失敗 大概率是模型不支持視覺輸入或者請求內(nèi)容過大被服務商拒絕。規(guī)劃層模型有輸出但規(guī)劃的動作明顯不對 比如點擊登錄按鈕規(guī)劃成了先點擊購物車。這種情況通常是模型對頁面理解有偏差換更強的多模態(tài)模型或把任務描述寫得更具體。執(zhí)行層規(guī)劃正確但 Playwright 報超時、元素不存在 看看頁面是否真的有彈窗、蒙層、懶加載把等待時間調(diào)大。驗證層操作全部完成但智能體仍然認為失敗 檢查斷言措辭是否太模糊比如檢查首頁正常就不如斷言頁面出現(xiàn) Products 標題明確。下面這張排查表我建議貼到團隊的 wiki 里現(xiàn)象可能原因最快解法401 / missing api key環(huán)境變量沒配檢查AI_API_KEY模型輸出為空 JSON模型不支持視覺換多模態(tài)模型規(guī)劃動作明顯錯誤任務描述太籠統(tǒng)把目標拆成更明確的子任務Playwright 點擊超時頁面彈窗、懶加載調(diào)大超時 先處理遮擋元素斷言反復失敗期望文案寫錯對照頁面實際文案修改任務描述6.2 實測中高頻遇到的五個坑這一節(jié)是我跑斷腿換來的經(jīng)驗逐條說坑一非多模態(tài)模型硬上一跑就掛。第一次我圖省事接了一個只支持文本的模型結(jié)果runTask執(zhí)行到第一步就報錯了。看日志才發(fā)現(xiàn)智能體需要看圖文本模型根本給不出有效規(guī)劃。換支持視覺的模型之后一切正常??佣laywright 瀏覽器內(nèi)核忘裝。裝完playwrightnpm 包直接跑腳本報錯Executable doesnt exist。跑一下npx playwright install chromium就解決。這是新手最容易卡住的一關??尤P蜏囟扰渲眠^高每次操作結(jié)果都不一樣。大模型默認的溫度參數(shù)可能偏高同一個任務每次規(guī)劃出來的步驟會漂移。做測試自動化時一定要把溫度調(diào)低理想情況設為 0讓輸出盡可能穩(wěn)定??铀娜蝿彰枋鎏\統(tǒng)。我試過直接說買一個背包模型在商品列表頁反復橫跳因為它不知道該點哪個商品。改成點擊名稱為 Sauce Labs Backpack 的商品圖片進入詳情頁之后一次就準了。任務描述越具體智能體越穩(wěn)定??游迕つ孔非笠淮闻艽罅坑美?。智能體每個任務都要多次截圖和模型推理Token 消耗遠高于普通接口調(diào)用。跑一百條 UI 用例的成本可能比跑一萬條接口用例還高。務必要把智能體用在刀刃上。6.3 成本控制token、超時與重試策略成本控制是 AI 測試能不能落地的關鍵。說幾個我摸索出來的硬指標一次簡單操作的 Token 消耗一個登錄任務大概會經(jīng)歷 3-5 次截圖和模型調(diào)用每次調(diào)用消耗幾百到上千 Token。一個復雜流程跑下來可能消耗上萬 Token。這個量級在可控范圍但如果你拿它跑全量回歸賬單會非??捎^??刂浦卦嚧螖?shù)默認情況下智能體失敗后會自動重試。建議設置合理的最大重試次數(shù)比如 2-3 次。再多就是浪費而且大概率是環(huán)境問題而不是智能體問題。把大任務拆小不要讓智能體從打開瀏覽器一路做到驗證數(shù)據(jù)庫?;A導航和等待用 Playwright 直接寫代碼完成只在關鍵決策點啟用智能體。比如page.goto(url)用代碼直接導航登錄、選擇商品、驗證結(jié)果這幾步交給智能體。這樣既省 Token又降低模型規(guī)劃出錯的概率。失敗現(xiàn)場一定要留證據(jù)無論報告還是截圖都要落盤。因為 AI 智能體的失敗往往是概率性的沒有現(xiàn)場截圖你很難判斷是模型規(guī)劃錯了還是頁面狀態(tài)不對。6.4 引入AI測試智能體的判斷標準與個人體會最后說說我的判斷標準這套標準現(xiàn)在是我們團隊決定要不要用 AI 智能體的參考如果團隊用例維護成本占測試開發(fā)時間超過一半值得試點。如果某條鏈路每次改版必紅優(yōu)先試點。如果頁面有大量動態(tài)元素、頻繁改版的組件優(yōu)先試點。如果幾千條用例都是點幾下、填個框、看結(jié)果的重復流程需要謹慎評估成本。我在實際項目中把一條支付鏈路交給了 midscene。剛開始的幾天它每天都會紅一兩次多數(shù)原因是模型對某些彈窗的誤判和頁面時序問題。后來統(tǒng)一了模型、把溫度降到 0、給任務描述加上了明確的邊界條件穩(wěn)定度明顯上去。最明顯的變化是前端改版之后以前我要花半天改選擇器現(xiàn)在只需要看一遍智能體的報告確認它通過視覺找到了新的元素位置然后把舊用例下線。當然我也必須說實話AI 智能體不會解決所有測試問題。數(shù)據(jù)斷言、精確計算、穩(wěn)定性保障這些仍然要依靠傳統(tǒng)的測試框架和斷言手段。它解決的是定位元素、維護選擇器、應對前端改版這一層最讓人頭疼的問題而不是整個測試體系。如果你正在考慮嘗試我的建議是不要從全量回歸開始選一條你最痛的核心鏈路花一個下午把環(huán)境搭起來跑通上面這個 Demo然后認真觀察一周。AI 測試這件事只有親手跑一輪你才能真切感受到把維護成本從寫選擇器轉(zhuǎn)移到人類表達意圖是什么體驗。