链载Ai

标题: 如何让AI帮你做前端自动化测试?我们这样落地了 [打印本页]

作者: 链载Ai    时间: 5 小时前
标题: 如何让AI帮你做前端自动化测试?我们这样落地了

本文介绍了一个基于AI的UI自动化测试框架在专有云质量保障中的工程化实践。


引言

随着AI大模型技术的快速发展并在各行业/场景下的爆发式应用,如何利用AI技术提高测试效率也成为了热门话题。具体到我们团队的日常工作中,一个痛点就是前端测试很耗费人力,体现在:

1. 前端用例自动化率低/无自动化,每个版本、每轮测试依赖手工执行,在多版本、快速迭代的背景下就会导致覆盖不足,漏到客户现场的前端缺陷多

2. 前端自动化实现门槛高、且维护成本大,在版本快速迭代的背景下,前端页面更新换代很快,会出现一个版本花大力气实现的自动化用例,在下个版本因为前端元素变动导致无法执行,还需要继续投入大量人力进行适配的情况

借助AI的能力,让解决这一痛点成为了可能,也即本文将要介绍的“基于AI的UI自动化测试框架”在专有云质量保障的工程化落地。


核心原理

技术栈

框架主要使用了开源的browser-use[1]工具,此外主要使用了如下技术栈:

架构

框架图

主要包括:

流程图

主要分为三个部分:

1. 测试任务的管理、调度、结果展示部分,即左上部分;

2. 测试用例的编写、维护、管理部分,即右上部分;

3. 测试执行的运行时管理部分,即下半部分;

实现机制

1. 自然语言驱动的测试用例

测试用例的编写采用yaml格式,将测试步骤以自然语言的方式编写为用例,框架会读取并分步以prompt提示词的形式与大模型交互,转换为具体的action调用。 下面是一个简单的VPC创建用例:

testType:ascmtestName:create_vpc_uniquetestId:74****98,74****3testDescription:使用默认参数创建VPCpreSteps:-common/product/ascm/login.yamltestSteps:-task:打开"{{ASCM_URL}}/vpc/console/vpcPage?{{DEFAULT_ORG_ID}}"-task:点击“创建专有网络”按钮#{{VPC_NAME_UNIQUE}}为用例自定义变量,参见py文件-task:在“专有网络名称”输入框输入“{{VPC_NAME_UNIQUE}}”-task:点击“提交”按钮

其中的重点在preSteps和testSteps:

关于提示词的组织原则,以及具体的实现原理,内容较多,后续会单独写一篇进行分析。

2. 动态元素定位

在传统的UI自动化实现中,一般会根据页面的xpath、css selector等方式,定位到具体元素然后进行后续操作。这也是维护成本高的一个主要原因,因为一旦页面排布发生变化,用例就无法执行。 browser-use在这里有较大的优势,它的稳定性好,是决定我们技术选型的一个重要因素。具体机制为:

3. 执行回放与自适应更新

使用AI的过程中有两个问题是必须要考虑的:

1. token使用量,在大量的测试用例自动化之后,多个环境、多个版本执行,会发起大量的大模型交互、消耗大量token

2. 大模型进行分析决策的速度问题,也即速度、效果、价格不能兼得,同时过程中会伴随着较多网络交互,也会影响用例的执行速度

基于这两个问题,框架支持了测试回放能力,即大模型决策生成的action调用和参数保存为json文件,在测试调度执行的时候,优先会执行json文件中内容的回放,这里完全不涉及大模型调用,并且用到了2中提到的index更新能力;若回放失败,再调用大模型执行,同时更新json文件为新生成的内容。

4. 断言机制

browser-use的设计目的是利用AI能力,分析用户给出的task并规划出相应操作浏览器的行为直至完成task。显然它是以目标为导向,自动化完成任务的一个工具,并不是天然为自动化测试设计的工具,所以它缺少测试需要的最关键一环,也就是断言。 测试框架补充了这一部分,在对应的task执行后,能够对当前浏览器页面进行元素抓取和结果判断。 框架设计上支持3种断言能力,当前已实现2种,1种实现中:

1. playwright原生断言能力,同样以前述创建VPC用例为例,最后一个task里可以这么写:

-task:点击“提交”按钮expected:-type:playwrightlocator:get_by_text("操作成功",exact=True)method:to_be_visible()

此处type告诉框架为playwright断言、locator为playwright的page locator支持的所有方法[5]、method为locator支持的所有expect assertion方法[6]这种方式的优点是即开即用,断言严格且准确,适合需要精确判断的用例场景

2. 用例自定义断言能力,type值改为validator,由测试用例自己实现validator函数并解析后续的yaml expected字段,以进行用例定制化的判断

3. 大模型断言(实现中),type值改为ai,调用大模型能力,对自然语言进行解析,结合当前页面元素、截图进行判断,可能存在不稳定性


实施过程中的挑战与解决方案

在框架的开发、用例实现和调试过程中,遇到了比较多的问题,这里挑几类典型问题及其应对方案进行介绍

1. 大模型幻觉问题

使用AI能力,就避免不了大模型产生幻觉,这是由大模型的概率特性所决定的。具体来讲,我们遇到了这几个问题:

虽然系统提示词中写明了"Don't hallucinate actions",大模型不会返回不存在的action,但在规划出具体应该使用什么action以及当前状态上,会出现和步骤task目的不匹配的情况。特别是在页面出现异常的场景下(如未完全加载成功),大模型会尝试使用scroll_down、go_back等多种action来操作,导致最终任务失败。解决方案采用了如下两种:

"action":[{"click_element_by_index":{"index":264}},{"wait":{"seconds":1}},{"done":{"text":"Clickedonthe'VPCID:vpc-ad7*******j9ap'linkandwaitedfor1second,taskcompleted.","success":true}}]

框架中的断言模块利用了browser-use的custom action能力,即扩展了大模型可以使用的function_calling tools。大模型看到task中需要进行断言时,会决策调用框架的expected action处理。实际使用中会出现两种非预期情况:大模型返回的决策结果中实际没有调用、断言失败后大模型误认为task没有完成而继续执行其它操作。

解决这两种情况依然是要从提示词入手,browser-use支持对系统提示词进行修改,即Override和Extend两种方式。框架采用的当然是Extend,browser-use的系统提示词是经过大量测试的,Override可能会导致很多稳定性问题。在系统提示词中,我们增加了如下章节:

REMEMBERthemostimportantRULE:1.ALWAYSuse'expected'toolwiththeprovidedexpectedstringinthetask2.If'expected'actionisnotsuccess,juststopthetaskanddonewiththemessage

2. browser-use与测试场景的适配

前文也有提到,browser-use的设计目的和我们工程化要应用的测试场景,还是有一些偏差的,在使用的过程中主要遇到两种问题:

我们遇到了诸如设置keepalive为True之后browser资源无法销毁、点击元素跳转到新tab后元素抓取仍然在原tab中进行等缺陷。有些缺陷在新版本的browser-use中修复了,有些还没有。 依赖browser-use本身的版本迭代无法满足我们的需求,因此框架层面直接将browser-use的核心对象派生后进行定制化修改。一方面可以快速修复发现的问题,这里的修复可能是直接解决问题、也可能是通过适配绕开问题;另一方面可以在已有功能的基础上,开发我们需要的功能,如Agent run方法的前后置hook接口,在history rerun时不支持,我们进行了补充,进而实现了每个测试步骤之后都能自动截图等功能,且大模型调用和回放执行效果一致。 这种方式避免了直接修改browser-use源码,因此后续升级browser-use版本不会存在冲突问题,同时又能享受开源社区贡献的成果。

我们的主要目的是实现UI自动化测试,browser-use并不能完成所有事情,因此在框架层面,对缺失的能力进行了补充实现,并完成了与browser-use功能的结合,主要为:

3. 页面元素识别问题

在测试用例自动化的过程中,基本流程是将人眼看到的页面元素,转换成prompt让大模型理解和定位,这里会存在不少gap,出现大模型死活给不出预期元素index信息的情况,我们采取了下面几种方式来改善这个问题:

结合用例调试过程,将与大模型进行交互的信息保存到日志中,辅助优化提示词,其中“[Start of page]”和“[End of page]”之间的内容,即为大模型真实看到的页面元素布局,其中的标签、属性、相对位置等信息能非常好的提升提示词编写的有效性,我们的测试用例编写规范中也针对这一部分进行了说明指导,如“新出现的xx”、“xx后面的yy元素”等。涉及的系统提示词中为如下部分:

-Onlyelementswithnumericindexesin[]areinteractive-(stacked)indentation(with\t)isimportantandmeansthattheelementisa(html)childoftheelementabove(withalowerindex)-Elementswith\*arenewelementsthatwereaddedafterthepreviousstep(ifurlhasnotchanged)


为了控制消耗的token,browser-use并不会抓取所有的页面元素信息传给大模型,如果某些特殊属性能帮助识别唯一元素,可以进行添加,对应如下参数:

include_attributes:list[str]=['title','type','name','role','aria-label','placeholder','value','alt','aria-expanded','data-date-format',],

有些时候并不一定要通过某些难定位元素来完成测试步骤,可以换个思路用一些简单、确定性强的方法组合起来达成目标。

如果确实无路可走,部分常用action其实支持指定xpath和css selector作为兜底,这种方式就会遇到传统UI自动化的问题,即页面布局变动可能导致定位失效。在一些动态页面的测试中,有过使用:

-task:鼠标移动到xpath为“//*[@id="icestarkNode"]/main/section[2]/section[2]/section[2]/section/section/div/div/div[1]/div[2]/div/div/div/div[2]/div[2]/table/tbody/tr/td[4]/div/div/div/div”的元素上-task:点击新出现的<i>元素

4. 测试稳定性

提升自动化用例的执行稳定性,是一个比较大的话题,也是一定需要解决的问题。特别是随着自动化用例数量、测试轮次的增加,无效执行的用例数量会增多,即非产品缺陷导致的用例失败。当前我们采用了下面几个方式:







欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5