当前位置:首页|资讯|ChatGPT|编程|提示词

ChatGPT生成单元测试实践(Golang)

作者:StuG_III发布时间:2023-03-18

前言

目前gpt本质上是续写,所以在待测函数函数定义清晰的情况下,单元测试可以适当依赖它进行生成。

收益是什么:

  • 辅助生成测试用例&测试代码,降低单元测试编写的心智成本

  • 辅助code review,帮助发现代码显式/潜在问题

本文测试环境:

  • gpt: gpt-3.5-turbo

  • go:go 1.17

本文实践场景:企业微信美图鉴赏机器人

生成单元测试的工作流如下:

  1. 选定你的待测函数

  2. 分析函数的依赖:结构体定义、repo依赖、repo interface抽象(用fx和wire等依赖注入框架的话会方便很多)

  3. 组织prompt,准备施法

  4. 吟唱魔法,得到输出单元测试代码

  5. copy到ide里面缝缝补补,与预期出入太多的话,调整prompt重来/要求gpt按照某个标准重写(比如:请按照testCases的写法重写组织测试数据)

  6. 运行测试用例

话不多说,先上基础prompt:

下面的部分,我按照工作流的繁杂程度,简单区分了下easy/normal/hard情况。

Part1 easy:单个函数,无复杂依赖

单个函数,并且外部依赖都是开源库,那么直接把代码贴上去就行。

这里我们用图片压缩的独立函数举例:(prompt前摇咒语 + 代码片段)

ChatGPT输出的代码块如下:

放到ide里,完美运行,说明简单函数的单元测试生成还是很强的~

完美运行,覆盖率100%

Part2 normal :里面有一些外部import

有外部定义引入的时候,最好把外部定义直接贴上(不涉及mock)。

这里举例的函数出现了外部依赖 entity.ArchiveWithData等定义,所以最好要加上外部定义在输入中:

下面是生成的代码,经过少量修改后可以直接运行:

(因为少输入了一个结构体的定义,导致它猜测了一些字段)

小修小补就能跑啦

Part3 hard:对外部repo进行mock(gomock举例)

外部依赖越多,prompt template的构建可能就越复杂

ps.实际上gomonkey它也可以写

外部依赖repo的部分,要求gpt使用gomock进行对应repo的mock即可。

外部定义最好进行剪枝。

输出:

生成的代码太长,几点总结:

1.gomock代码可以正常生成,但是外部repo定义最好清晰明了,可以直接把interface定义贴上去,会被认知到。

2.粘贴到ide中,发现主要问题是包名导入问题,简单修改即可

类型&package名错误
小修小补

修改后运行成功:

run!

如果需要生成后人工修改量更低的话,需要更精确的上下文信息(包名、函数定义、描述等)

一些痛点

1.需要外部 repo mock的待测函数,需要的上下文很多,并且引入的无关字段需要剪枝避免污染输入

2.一些复杂的私有包,看起来是比较不好支持的(尝试过在prompt中教会他,但是效果不好)

3.一些复杂逻辑和边界情况,ai可能口是心非(写的用例和表述不一致,比如经典的20%*20%=400%,但是他知道这是错的)

4.对于分层不是很清晰的项目,对函数/repo打桩可能很困难,这个时候要描述清楚就比较困难了,gomonkey可能比较适用

其他用法

1.写好测试方法,让gpt帮助扩充用例集

2.code review,下面的代码就是gpt给出的代码建议

ChatGPT给出的优化建议:



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1