AI驱动的UI自动化测试教程:基于Midscene.js+Playwright
📝 面试求职: 「面试试题小程序」 ,内容涵盖 测试基础、Linux操作系统、MySQL数据库、Web功能测试、接口测试、APPium移动端测试、Python知识、Selenium自动化测试相关、性能测试、性能测试、计算机网络知识、Jmeter、HR面试,命中率杠杠的。(大家刷起来…)
📝 职场经验干货:
在入门Midscene前,部分同学会担心因为自己不懂JavaScript而导致上手困难,其实大可不必有这样的顾虑。
首先,Midscene的设计理念就是用自然语言描述UI自动化测试,它的核心 API 设计得非常简单易用,即便对 JavaScript 不熟悉,只要具备一定编程基础(如掌握 Python),也能迅速上手。
其次,当下各类强大的 AI 代码助手与 AI IDE 层出不穷,像 VSCode 的 Roo Code 插件,以及字节出品的 Trae 等,这些工具足以解决大部分编程难题。
就我个人而言,此前我主要使用 Python,对 JavaScript 并不熟悉,但如今也能轻松入门 Midscene。

想要快速入门 Midscene,你只需要掌握以下3个核心 API就能完成绝大部分简单的自动化任务:
1.UI交互操作
function aiAction(prompt: string): Promise<void>;
function ai(prompt: string): Promise<void>; // aiAction简写形式
这个方法允许你通过自然语言描述 UI 操作步骤,Midscene 会自动规划这些步骤并执行。
示例
await ai("点击登录按钮");
await ai("在用户名输入框中输入用户名:test111");
await ai("输入验证码"); //AI会自动识别验证码并输入验证码
2.断言
function aiAssert(assertion: string, errorMsg?: string): Promise<void>;
这个方法允许你用自然语言描述断言条件。
示例
await aiAssert('"Sauce Labs Onesie" 的价格是 7.99');
3.数据获取
function aiQuery<T>(dataShape: string | Object): Promise<T>;
这个方法允许你用自然语言描述数据的获取方式。
使用此方法,你可以直接从 UI 提取结构化数据,并借助多模态 AI 的推理能力,实现智能提取。只需定义期望格式(如字符串、数字、JSON、数组等),Midscene 即返回相应结果。
示例
//在以下的例子中,dataA 将是一个对象,包含 time、userInfo、tableFields 和 tableDataRecord 四个字段。
//其中,time 是一个字符串,userInfo 是一个对象,tableFields 是一个字符串数组,tableDataRecord 是一个对象数组。
const dataA = await agent.aiQuery({
time: '左上角展示的日期和时间,string',
userInfo: '用户信息,{name: string}',
tableFields: '表格的字段名,string[]',
tableDataRecord: '表格中的数据记录,{id: string, [fieldName]: string}[]',
});
// dataB 将是一个字符串数组
const dataB = await agent.aiQuery('string[],列表中的任务名称');
// dataC 将是一个包含对象的数组
const dataC = await agent.aiQuery('{name: string, age: string}[], 表格中的数据记录');
aiQuery比起aiAssert的优势在于,它支持更复杂和更可靠的页面断言。
用aiAssert难以描述复杂的数据结构和复杂的断言规则,而且,aiAssert的断言有可能不够准确,因为AI大模型可能存在一定的”幻觉“。
比如,上面那个例子中,存在这样的风险:页面上的价格数值是7.98而不是7.99,但AI模型在提示词的引导下可能会错误地把界面上的7.98当成7.99,并让断言通过了。
为了降低因 AI 幻觉导致错误断言的风险(例如遗漏错误),推荐使用 aiQuery 加上常规的 JavaScript 断言来补充或者替代 aiAssert。
例如,可以这样替代上面的断言代码:
const items = await aiQuery(
'"{name: string, price: number}[], 返回商品名称和价格列表'
);
const onesieItem = items.find(item => item.name === 'Sauce Labs Onesie');
//使用常规的 JavaScript 断言来验证价格是否正确
expect(onesieItem).toBeTruthy();
expect(onesieItem.price).toBe(7.99);
4.即时操作
在以上的基础API之外,Midscene还提供了一些进阶使用的API。首先,上面所讲的ai接口是一个 自动规划接口,使用的时候,Midscene会调用LLM来理解用户的自然语言指令和规划操作步骤,然后执行它们。可以在报告中ai的整个过程:

从图中可以看到,ai会有三个步骤:
-
Planning:规划步骤
-
Insight / Locate:定位元素
-
Action:执行操作
这个接口的好处是,它比较”智能“,更像流行的AI Agent风格,允许大模型自动规划操作步骤并自主决定调用哪个底层操作的API。
但它也有一些缺点,比如:它的效果依赖于AI模型的质量,当使用复杂prompt时,模型可能规划出错误的步骤,而且Planning步骤可能会耗时较长。
为了解决这个问题,从Midscenev0.14.0开始引入了即时操作(Instant Actions) 功能,包括 aiTap(), aiHover(), aiInput(), aiKeyboardPress(), aiScroll() 接口。
这些接口会直接执行指定的操作,而AI模型只负责底层任务,如定位元素等。使用这些接口后,整个过程可以明显更快和更可靠。这些接口的使用方式如下:
//点击元素
await aiTap('登录按钮');//点击登录按钮
//悬停元素
await aiHover('设置按钮');//悬停在设置按钮上
//输入文本
await aiInput('用户名输入框','test111');//在用户名输入框中输入文本
//键盘操作
await aiKeyboardPress('Enter');//按下Enter键
//滚动页面
await aiScroll({direction:'down',scrollType:'untilBottom'},'搜索结果列表');
使用这些接口的脚本看起来似乎增加了API的复杂度(或者不太“智能”),但实践证明使用这些结构化的接口确实是一个节省时间的好方法,尤其是在操作已经非常明确的时候。
即使操作接口和ai接口如何选择,本身没有绝对的标准,而是取决于具体的测试场景和需求。本质上这还是一个效果和效率的平衡问题,更细粒度的控制可以让测试更加准确可靠,但也会增加脚本的编写成本和维护成本。
5. 等待操作
还有就是大家非常关心的:自动化测试中必不可少的等待操作怎么实现?
众所周知,自动化测试失败率高的首要原因之一是元素还没有加载完成导致的元素定位失败。在这种情况下,我们需要等待页面或指定元素加载完成。
首先,可以使用传统的强制等待方法,指定等待时间。
await page.waitForTimeout(5000); // 等待 5 秒
这种方法不够灵活,会导致脚本的执行时间变长,影响测试效率。为了解决这个问题,Midscene引入了智能等待 功能,使用aiWaitFor() 接口,只需用自然语言描述等待条件即可。
await aiWaitFor('出现用户归属部门选择弹窗');
6. 指定类型数据提取
另外,aiQuery()接口也衍生出一些更加便捷的API。比如,如果只是提取字符串、数字和布尔值等简单类型的数据,就无需在提示词中描述提取的数据类型,而是可以直接使用以下方法:
const bool = await aiBoolean('是否存在登录对话框');
const title = await aiString('页面标题');
const price = await aiNumber('商品价格');
还要说明一点:在官方文档中,以上所有的API都带上了 agent. 前缀。而在 Playwright 中,这些调用是不带 agent. 前缀的,只有在使用其他框架(比如Puppeteer)或者做安卓自动化的时候才需要带上这个前缀。
本系列将持续更新Midscene.js实操教程,想要学习Midscene.js的同学欢迎点赞转发加收藏, 关注我的公众号,学习更多AI+测试相关的知识。
最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】
更多推荐
所有评论(0)