ChatGPT辅助编写自动化测试

news/2025/2/12 3:32:45/

大家好,我是洋子,ChatGPT已经越来越火爆,国内百度、阿里等互联网大厂也纷纷投入大模型研究,OpenAI官网中提供了许多ChatGPT应用场景,例如SQL翻译、语言翻译、代码解释等

作为一名QA,我更关注ChatGPT生成的自动化测试脚本质量如何,借助ChatGPT能否提升自动化测试编写效率

当提到自动化测试时,我们通常将其分为单元测试、接口测试和UI测试,接下来,我们先看看ChatGPT生成的单元测试代码的质量如何

ChatGPT辅助后补单元测试

首先,使用Spring框架编写一个简单的后端服务,服务包括两个接口:一个createUser接口和一个getUsers接口,使用“spring-boot-starter-data-jpa”连接、操作数据。service层的代码实际上没有业务处理逻辑,只是调用了Repository中的方法而已

为了让ChaGPT为service层的代码编写单元测试,Prompt中的要求如下:

Prompt中要求使用JUnit5Mockito框架。
Prompt中要求使用@Mock@InjectMocks注解。
Prompt中给出了UserServiceImpl中的createUser()方法的源代码。

ChatGPT生成了两个测试用例:一个正向测试用例和一个异常测试用例。将这些代码复制到IDE中,基本上无需修改即可成功运行。通过这个实验,可以看到,对于简单逻辑的代码,ChatGPT生成的单元测试代码质量较高

在这里插入图片描述

在上面的例子中,介绍了如何编写Service层的单元测试。如果希望编写Controller层的单元测试,只需稍微修改Prompt,在Prompt中要求使用Spring框架提供的MockMvc编写单元测试即可。除了单元测试,针对后端服务,也建议编写少量容器内的集成测试,以覆盖Controller层到DB层的代码

修改Prompt,在Prompt中要求使用@SpringBootTestTestRestTemplate编写集成测试。实验结果如下,将生成的代码复制到IDE上,几乎无需任何修改即可成功执行。
在这里插入图片描述

总结而言,对于逻辑比较简单的代码,ChatGPT生成的单元测试和集成测试代码质量较高,基本可以直接运行,或做很小的修改即可运行。接下来,继续探索对于稍微复杂的代码,ChatGPT生成的单元测试质量如何。下图是特意编写的一个包含很多分支逻辑的方法,源代码中包含一个public的toLocal()方法和几个private方法,toLocal()方法会调用这些私有方法。Prompt和生成的单元测试如下所示
在这里插入图片描述

  1. 由于代码中存在很多分支逻辑,适合参数化测试数据,因此Prompt中要求使@Parameterized
  2. 将生成的测试代码复制到IDE中运行,会发现部分单元测试运行失败。经检查发现,部分单元测试与源代码的逻辑不符,这表明对于稍微复杂的代码,ChatGPT生成的单元测试仍需要人工干预来进行修正。
  3. ChatGPT生成的单元测试覆盖率在30%-40%左右,如果继续要求ChatGPT补充更多的单元测试,ChatGPT可能会生成一些与上一个版本重复的单元测试,或者给私有方法添加单元测试。这表明对于分支逻辑较为复杂的代码,ChatGPT生成的单元测试覆盖率不够,剩余的部分需要人工进行补充。

当然,上面都是针对遗留系统需要后补单元测试的情况,如果是新系统的开发,我们更加推荐采用TDD的方式,而不是在后期补充单元测试。

ChatGPT辅助编写接口自动化测试

如果要为一个接口编写自动化测试,除需确定测试框架外,还需构建接口的Request、Response Object。以选用Java技术栈为例,可以选用Lombok来灵活构建接口的Request body,使用jackson完成object和json string的转换。下图是ChatGPT生成的接口自动化测试结果,接口测试代码质量较高,几乎无需修改即可成功运行。
在这里插入图片描述

当然,上述实验仅为单个接口生成接口测试。在实际项目中,接口测试还涉及多个接口间的值传递、配置信息管理、测试数据管理等问题。从测试场景的角度来看,即便是测试同一个接口,也需要构建不同的Request body以测试接口的返回内容是否符合预期。实际,对于这些任务都可以通过任务拆解、提供不同的Prompt来完成。例如,对于多个接口之间的值传递场景,可以在Prompt中先提供第一个接口的信息,生成代码后,再提供第二个接口信息,在生成的代码基础上稍微调整,即可完成不同接口间值传递场景。总结而言,利用ChatGPT可提高编写接口自动化测试的效率。

ChatGPT辅助编写Web UI自动化测试

当搜索“ChatGPT auto write test”时,发现排在前面的大多数是关于“如何使用ChatGPT编写web UI自动化测试”的文章,这似乎有些奇怪,因为编写Web UI自动化测试需要定位Web页面上的目标元素,而ChatGPT并不知道被测Web系统的页面结构。从原理上来说,ChatGPT无法编写UI自动化测试,那么ChatGPT真的能编写Web UI自动化测试吗?

先来看下第一个例子,让ChatGPT使用Cypress对一个公共网站“https://angular.realworld.io/” 编写UI自动化测试,测试场景涉及三个页面。生成的自动化测试质量很高,除了登录页面上的两个元素定位错误外,其他部分基本正确。并且,按照Prompt中要求的Page Object模式生成代码,因此,只需稍微修改即可成功运行。当我做到这个实验时,我觉得很奇怪,为什么页面元素定位准确率这么高?我尝试询问ChatGPT是否会爬取页面结构,ChatGPT回复并没有。
在这里插入图片描述

为了搞清楚这个问题,我做了第2个实验,编写了一个包含注册、登陆、添加todoList的简单web系统,本地启动后,让ChatGPT为这个web系统编写UI自动化测试脚本,测试场景涉及三个页面。此次生成的脚本质量较差,部分元素定位错误,第三个页面总共有5个页面元素,ChatGPT只定位了2个,且定位元素的selector也不正确。但是通篇没有任何留空白的地方,在这里,我们也看到了ChatGPT如何一本正经地胡说八道。
在这里插入图片描述

从上面的实验来看,即使是本地启动的Web系统,ChatGPT仍然可以正确定位少量页面元素。经过分析和观察,我猜测ChatGPT大概是根据Prompt中的信息猜测元素的类型,然后选用可能性较高的一种方式来定位页面元素。例如,Prompt提供如下信息:

  1. 进入https://xxxx
  2. 点击“signup”菜单
  3. 输入username、password

ChatGPT结合上述信息,会猜测“signup”菜单是一个链接,因此会选用Cypress中的“cy.contain(“signup”)”来定位该元素。它还会猜测username和password是input类型的元素,因此会选择使用Cypress中的“cy.get(‘input[name=”firstname”]’)”来定位这些元素。当然,如果你多次生成,有些元素的定位方式可能会从CSS修改为ID定位等其他方式。

为了进一步验证上面的猜测,我进行了第3个实验。在这个实验中,Prompt中明确告知ChatGPT第三个页面需要输入“title,desc”,选择“status和targetDate”。通过这个信息,ChatGPT就知道了第三个页面总共有四个需要定位的元素。其中,前两个是Input类型的元素,后两个是多选框。对于多选框,生成的代码中,ChatGPT用cy.get(“…”).select(“…”)的方式进行定位。虽然还是没有定位到目标元素,但语法格式正确,与上一次生成的脚本相比,脚本质量有所提高。
在这里插入图片描述

从上面的几个实验结果来看,基本证实了ChatGPT确实是根据Prompt中的信息,猜概率的方式编写UI自动化测试,它并不真正知道目标web系统的页面结构。但是,如果是猜概率,为什么第一个public的web系统元素定位正确率这么高呢?难道是public的网站定位正确率高,private的低?

为了解决这个疑惑,我写了另外一个Prompt,让ChatGPT登陆我司官网,生成的脚本质量并不高。下面的实验1是让ChatGPT登陆我司网站,生成的代码中第一个元素定位正确,后面两个均错误。实际系统中,登陆首页并没有password输入框和submit按钮。接着,做了第2次实验,在Prompt中描述了更详细的操作步骤,生成的脚本中元素定位正确率依然很低,只是比第1次有所提高而已,详细结果如下所示:
在这里插入图片描述

同样都是public的网站,编写的脚本代码质量差异很大,这说明可能和训练的数据有关。联想到ChatGPT基于github上的代码做训练,大概率是github上有很多UI自动化测试代码,用第一个public的网站作为测试对象(备注:我自己就用不同的UI测试框架测试过第一个public网站,且代码也在github上)。所以,如果是某些常见场景,例如打开google,查找某个信息等,ChatGPT生成的脚本质量可能较高。反之,如果是内部web系统或者新上线的系统,生成的脚本质量就较差。

实际项目中有很多是ToB系统,且要求自动化测试和新功能实现同步完成。鉴于ChatGPT数据训练来源于github,如果用ChatGPT为实际项目中系统生成web UI测试代码,因为页面元素定位正确率很低,故生成的UI测试代码帮助很有限。

总结

总的来说,如果一个系统需要后补单元测试,可以考虑借助ChatGPT生成单元测试和容器内的集成测试。如果源代码中类的代码行数太多,建议逐个方法输入以生成测试,避免遇到ChatGPT单次tokens限制。此外,还可以通过任务拆解的方式为项目从0开始构建完善的接口自动化测试。对于Web UI自动化测试而言,由于ChatGPT无法知道页面的结构,虽然可以生成UI自动化测试脚本,但元素定位的准确率很低,对实际项目的帮助很有限


http://www.ppmy.cn/news/1074553.html

相关文章

vue3+ts封装弹窗,分页封装

定义defaultDialog .vue <script lang"ts" setup> import { ref,toRefs,onUpdated } from vue import { ElMessageBox } from element-plus const props defineProps({//接收参数&#xff0c;父组件传的时候用:msg123的形式msg:String,show:{type:Boolean,defa…

Web网站服务器

目录 一、什么是Apache? 二、虚拟目录是什么&#xff1f; 三、Apcahe相关配置文件 四、httpd.conf主配置文件的常用配置参数 五、Web网站配置案例 5.1搭建基于用户的个人主页网站 5.2、配置虚拟目录 5.3、配置虚拟主机 5.3.1搭建两个基于IP地址的虚拟主机 5.3.2搭建两个基于域…

【跟小嘉学 Rust 编程】二十、进阶扩展

系列文章目录 【跟小嘉学 Rust 编程】一、Rust 编程基础 【跟小嘉学 Rust 编程】二、Rust 包管理工具使用 【跟小嘉学 Rust 编程】三、Rust 的基本程序概念 【跟小嘉学 Rust 编程】四、理解 Rust 的所有权概念 【跟小嘉学 Rust 编程】五、使用结构体关联结构化数据 【跟小嘉学…

关于JavaScript中Set的操作和应用

目录 JavaScript中Set的操作和应用Set的基本操作创建Set添加元素删除元素判断元素是否存在获取Set的长度清空Set Set的遍历for...of循环forEach方法转换成数组后遍历使用Set的entries方法遍历 Set的应用数组去重判断两个数组是否有重复元素实现并集、交集和差集 总结 JavaScrip…

webpack loader和plugins的区别

在Webpack中&#xff0c;Loader和Plugin是两个不同的概念&#xff0c;用于不同的目的。 Loader是用于处理非JavaScript模块的文件的转换工具。它们将文件作为输入&#xff0c;并将其转换为Webpack可以处理的模块。例如&#xff0c;当您在Webpack配置中使用Babel Loader时&…

postgresql-通用表表达式

postgresql-通用表表达式 简介简单 CTE递归 CTE案例1案例2 DML 语句与 CTE 简介 通用表表达式&#xff08;Common Table Expression、CTE&#xff09;是一个临时的查询结果或者临时表&#xff0c;可以 在其他 SELECT、INSERT、UPDATE 以及 DELETE 语句中使用。通用表表达式只在…

华为OD机试 - 数字序列比大小 - 贪心算法(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 A&#xff0c;B两个人万一个数字比大小的游戏&#xff0c;在游戏前&#xff0c;两个人会拿…

kafka+Kraft模式集群+安全认证

Kraft模式安全认证 前章内容聊到了Kafka的Kraft集群的配置及使用。本篇再来说说kafka的安全认证方面的配置&#xff0c;。 Kafka提供了多种方式来进行安全认证&#xff0c;包括身份认证、授权和加密传输。一些常用的Kafka安全认证方式&#xff1a; SSL/TLS&#xff1a;使用S…