当前位置:AIGC资讯 > AIGC > 正文

通过实时调试,让AI编写有效的UI自动化

作者简介

Thales Fu,携程高级研发经理,致力于寻找更好的方法,结合AI和工程来解决现实中的问题。

引言

在快速迭代的软件开发周期中,用户界面(UI)的自动化测试已成为提高效率和确保产品质量的关键。然而,随着应用程序变得日益复杂,传统的UI自动化方法逐渐显露出局限性。AI驱动的UI自动化出现了,但仍面临着准确性和可靠性的挑战。在这个背景下,本文提出一个创新的视角:通过实时调试技术,显著提升AI编写的UI自动化脚本的有效性。

这个问题不仅仅是技术上的挑战,它关系到如何在保证软件质量的同时加速软件的交付。本文将探讨实时调试如何帮助AI更准确地理解和执行UI测试脚本,以及这种方法如何能够为软件开发带来革命性的改变。

一、UI自动化的现状

从最初的记录与回放工具到复杂的脚本编写框架,UI自动化经历了显著的发展。然而,尽管技术进步,传统的UI自动化方法在应对快速变化的应用界面时仍然面临诸多挑战。

手动编写测试脚本不仅效率低下,而且在应用更新时需要大量的重新工作。据行业调查显示,UI自动化测试脚本的维护可能占到整个测试工作的60%至70%。在一个典型的敏捷开发环境中,每次应用更新可能需要超过100小时来重新编写和测试现有的自动化脚本。这种高昂的维护成本凸显了传统UI自动化方法的低效性和资源消耗。

二、行为驱动开发BDD的引入

行为驱动开发(BDD)是一种敏捷软件开发的实践,它鼓励软件项目的开发者、测试人员和非技术利益相关者之间进行更有效的沟通。Cucumber是实现BDD方法论的一个流行工具,它允许团队成员使用自然语言编写明确的、可执行的测试用例。

Cucumber使用一种称为Gherkin的域特定语言(DSL),这种语言是高度可读的,使得非技术背景的人员也能理解测试的内容和目的。测试场景被写成一系列的Given-When-Then语句,描述了在特定条件下系统应该如何响应。

例如,一个在线购物网站的购物车功能可能有如下的Gherkin场景:

这种方法通过使用自然语言描述功能,帮助技术和非技术团队成员之间建立更好的理解和沟通。自然语言的测试场景也充当了项目文档,帮助新团队成员快速理解项目功能。让非技术人员可以直接参与测试用例的编写和验证过程,确保开发工作与业务需求紧密对齐。

但是它也存在着局限性,尽管测试场景用自然语言编写,每个步骤背后的实现(步骤定义)仍然需要技术人员使用编程语言来编写。这意味着实现测试逻辑可能涉及复杂的代码编写工作。随着应用程序的发展和变化,维护和更新与之相对应的测试步骤可能会变得繁琐。特别是在UI频繁更改的情况下,相关的步骤定义也需要相应地进行更新。还有灵活性和适应性限制:Cucumber测试脚本依赖于预定义的步骤和结构,这可能限制测试的灵活性。对于一些复杂的测试场景,实现特定的测试逻辑可能需要创造性地规避框架的限制。

三、当前AI在UI自动化中的应用

近年来,AI技术被集成到UI自动化中,特别是以GPT为代表的大模型出现后,因为它本身就有代码生成能力。业界也开始试着通过大模型来直接把Gherkin的测试用例描述语言生成成测试代码。

不过,当前大模型生成的测试代码并不能完全达到预期,主要有几个问题:首先,生成出来的脚本,因为语法错误可能无法运行;其次,也可能没有准确的覆盖到测试用例需要它去测试的校验点。在我们的实践下,真正能第一次就成功的比例不超过5%。

它生成失败后,接着就需要人介入再进行一些补救的工作。包括:调试,修改用例重新生成,或者直接修改生成的脚本。

而这些工作本身也需要消耗不少的人力,和我们系统通过AI来自动生成测试脚本的初衷相违背。

四、AI全自动的来编写有效的测试脚本

为了解决这个问题,我们重新思考了AI生成测试脚本的整个过程。

我们把人的工作也放在里面一起考虑。人在系统中做了调试和修改的工作,那这部分工作是不是可以让AI来做呢,让系统自己运行生成的代码,让AI来调试和修改自己生成的错误代码。

因此,我们调整了系统设计,让AI代替人自主地来做这些工作。最终,对于携程酒店订单详情页的全部用例,在无人参与的情况下,生成可以执行成功的占全部的83.3%,在生成脚本过程中,有8%的case就已经发现了Bug。我们连续生成这些用例三次,成功率分别在84.3%,81.4%和83.3%,系统是稳定有效的。

具体的测试用例和代码如下:

首先,需要滑动到订单详情页下放的用户权益模块,然后点击订房优化区域,来弹出价格浮层。

然后再看,费用明细里面是否包含黑钻贵宾。

最终生成的测试代码如下:

五、系统实现

整个系统的核心架构示意图如下。系统的核心部分是一个langchain框架的程序。它会去访问大模型,我们给它配备了多个工具,主要分成两类,一类是页面信息的获取工具,一类是调试工具。

Langchain会自动根据需要,使用页面信息获取工具,去拿页面的数据,来判断当前的操作需要具体哪个控件,来生成代码。然后再使用调试工具在手机中真实的执行代码,基于调试的反馈来判断自己生成的代码是否正确。

5.1 提示词

有了基本的架构后,我们需要提示词,来把这些工具粘合起来,让AI理解它该如何工作。我们的提示词从结构上来说包含了几部分内容:首先告诉AI它该如何思考和工作,其次告诉它一定要通过Debug调试它每一句生成的语句,再次告诉它输出格式是什么,最后是告诉AI要处理的完整用例文本。

对于告诉AI它该如何思考和工作,展开包含以下部分:首先看页面有哪些模块,我要操作的这个步骤应该是哪个模块,这个模块里有哪些控件和组件,我当前要操作的是哪个控件或组件,我要操作的动作是什么,以及我可以用的特殊的语法是什么,然后生成语句。

5.2 调试工具

调试工具的本质是通过adb工具远程连接到手机上。连接后,我们就可以把AI生成的指令发送给手机去运行,并且读取到运行后的结果给到AI,让AI去判断自己生成的指令是否正确。

5.3 页面信息获取工具

页面信息获取工具的最终目的是帮助AI判断出,BDD的用例上面写得要操作的内容,它具体要操作的控件的ID是什么,有了ID才能基于ID生成后续的程序指令。而为了拿到ID,我们需要有个控件和组件库,这个库里面的核心是每个控件和组件的ID以及它们的描述。有了这两项内容后,才能帮助AI看了BDD用例后,基于控件的描述去猜需要的是哪个控件。

为了达到这个目的,我们建立了一个页面控件库。这个库除了包含页面上每个控件的ID和描述外,还包含了页面和组件的关系,以及组件和控件的关系。能方便AI一步步的进行查询。

而这个控件库本身是基于我们通过job对代码进行静态分析来生成的。不过实际应用中,因为页面当前真正展示的控件会根据场景状态的不同而不同,在某些场景下页面上的控件会隐藏。因此页面信息获取工具会把页面当前真实存在的控件和控件库中查询出来的控件做交集,从而获取到当前页面真实展示出的控件和它的描述信息。

5.4 进一步拆分AI

当做了这些工作后,AI基本上已经可以把上面这张图黄色的部分,也就是人的工作自动去做了。生成成功率也从5%提升到了55%,但是55%的成功率还是不够的。

我们进一步分析了失败的case。发现主要问题是AI的幻觉,虽然提示词已经比较详细了,但是AI有时会没有按照要求处理,有的时候会自己胡说八道。

我们的结论是,给AI的责任太多了,它要考虑的东西太多。倒不是说它的Token不够,而是让它做的事情太多,会遗忘,无法精准完成要求。因此我们考虑进行拆分,还是利用了langchain的function的功能,既然AI能通过工具去完成功能,那这个工具为什么本身不能也是个AI呢。

甚至还可以把它再进行拆分。

通过这些拆分,我们让每一个AI需要考虑的工作变得更少更简单,也让它处理得更加精准,最终生成成功率提升到了80%以上。

六、后续的发展

当前,通过我们的工作,能让AI在无人参与下以80%左右的成功率去生成自动化测试的代码,很让人振奋,但还有很多问题需要继续去解决。

1)大模型的调用成本还是不低,是否有更好的办法,更低的成本去完成工作。

2)当前还有些比较难处理的操作或者校验,成功率80%还有不小的提升空间,以及目前最后还是需要人来复核生成结果。

3)除此之外,其他方面也都有提高的空间,值得我们继续去完善。

更新时间 2024-03-15