Synthesizing File-Level Data for Unit Test Generation with Chain-of-Thoughts via Self-Debugging
本文提出了一种新颖的自调试数据蒸馏方法,该方法能够生成带有忠实思维链解释的高质量单元测试训练样本,从而使微调后的模型在测试断言通过率、分支覆盖率和变异得分方面显著超越最先进的商业模型。
原始论文采用 CC BY 4.0 许可(http://creativecommons.org/licenses/by/4.0/)。 这是对下方论文的AI生成解释。它不是由作者撰写或认可的。如需技术准确性,请参阅原始论文。 阅读完整免责声明
想象一下,你正在试图教一名非常聪明但缺乏经验的学徒如何为一台复杂的机器编写说明书。这份手册必须是完美的:它必须准确解释机器是如何工作的,并且必须包含一套“压力测试”,以证明机器在极限状态下也不会损坏。
这篇论文介绍了一种名为 Repo-Smith 的新方法,旨在帮助人工智能(大语言模型)学习如何编写这些完美的软件代码压力测试。
以下是他们实现这一目标的创作故事,使用了简单的类比:
问题所在:“复制粘贴”型学徒
通常,当我们想要教 AI 编写软件测试时,我们会向它展示来自真实世界项目的示例。
- 问题在于: 现实世界的测试虽然很棒,但它们并没有附带一个“思考过程”。这就像是给学徒看一个做好的蛋糕,却没告诉他们为什么要加糖,或者如何知道烤箱已经热好了。
- 另一种选择: 我们可以要求 AI 在编写测试的同时,直接“编造”一个思考过程(思维链/Chain-of-Thought)。但论文发现,当 AI 试图解释它刚刚凭空捏造出来的测试时,它经常会撒谎或产生混乱。这就像学徒试图解释一个自己临时凑出来的食谱;他们可能会忘记某个步骤,或者发明一些虚假的配料。
解决方案:“自我纠错”工作坊
作者创建了一个名为 Repo-Smith 的系统,它扮演着“大师级工匠工作坊”的角色。该系统不仅仅是要求 AI 写一次测试,而是让 AI 经历一个严苛的训练循环。
把它想象成一款电子游戏,AI 必须通过某个关卡(编写测试),但如果失败了,它会得到提示并必须重新尝试。
第一步:第一次尝试(草稿)
AI 查看一段代码(“目标文件”),然后尝试编写一个测试文件并解释其思考过程。
- 类比: 学徒编写了一份压力测试说明书的草稿。
第二步:“自我调试”循环(试运行)
这是神奇之处。系统会在真实的计算机环境中自动运行 AI 刚刚编写的测试。
- 如果测试崩溃了: 系统会告诉 AI:“你试图打开一扇不存在的门。请修复你的导入语句(import statements)。”
- 如果测试运行成功但答案错误: 系统会说:“你检查错了选项。请修复你的逻辑。”
- 如果测试运行成功但遗漏了某个角落: 系统会说:“你没有测试机器的背面。请为那个部分添加一个测试。”
随后,AI 必须修复其错误并编写一个新版本的测试。它会反复进行这个过程(最多 5 轮),每次都变得更好。
第三步:“压缩”(最终教训)
这是一个聪明的技巧。在 AI 修复错误后,它拥有了一段冗长且混乱的历史记录:“起初我以为是 X,然后我意识到我错了,接着我尝试了 Y,然后我看到了一个错误,然后我修复了它……”
系统要求 AI 将这段混乱的历史记录压缩成一个干净、完美的完整故事。
- 类比: 想象学徒写了一本 50 页的关于其错误与修正的日记。系统要求他们将其重写为一份精简且完美的 2 页指南,内容为:“你应该如何构建这个测试,包括我们从中吸取的教训。”
- 这创造了一个高质量的“思考过程”,因为这个过程是真实的,因为它确实引导出了一个可运行的测试。
结果:超级学徒
研究人员利用这种方法创建了一个包含 74,518 个示例的海量数据集。每个示例都包括:
- 待测试的代码。
- 完美的测试文件。
- 解释如何达到该结果的完美、压缩后的“思考过程”。
随后,他们用这个数据集训练了一个新的 AI 模型。结果令人印象深刻:
- 该 AI 编写的测试通过率达到了 36.17%(相比之下,当时最优秀的商业模型约为 27%)。
- 它覆盖了更多的代码部分(43.90% 的分支覆盖率)。
- 它在发现隐藏漏洞方面表现得更出色(88.66% 的变异得分/mutation score)。
核心启示
这篇论文证明了你不需要由人类来为每一个测试编写“思考过程”。相反,你可以让 AI 编写测试,让它失败,让它自我修复,然后要求它总结它是如何修复自己的。这创造了一个高质量的训练数据集,使得 AI 在编写软件测试方面比以前聪明得多。
简而言之:Repo-Smith 将 AI 的错误转化为了它最好的老师。
您所在领域的论文太多了?
获取与您研究关键词匹配的最新论文每日摘要——附技术摘要,使用您的语言。