✨ 要点🔬 技术摘要
想象一下你是一位大厨,正试图教一位非常有天赋但有时过于急躁的 AI 助手如何烹饪一道特定的菜肴。你有一张“金标准”食谱卡(即人工测试集),上面详细列出了这道菜应该是什么味道,以及如何检查是否做得正确。
这篇论文讨论的是让 AI 编写它自己的“味觉测试”来判断菜肴是否美味,并研究如何更好地向它提问。
以下是使用简单类比对这项研究进行的拆解:
问题所在:“黑盒”式的 AI 测试
软件开发人员使用 AI 来编写测试(确保代码正常工作的检查)。但通常,我们只检查 AI 的测试是“通过”还是“失败”,或者它们覆盖了多少行代码。这就像是在检查一个学生是否在数学考试中得到了正确答案,却不去观察他们是如何思考问题的。
研究人员想知道:AI 真的理解了问题的不同“风味”(场景),还是仅仅在瞎猜?
三种提问方式(提示策略)
研究人员尝试了三种不同的方式来与 AI(使用 GPT-4o)交流以生成这些测试。你可以把这些看作是三种不同的向副厨师索要品鉴菜单的方式:
直接实现(“直接做”法):
提示词: “这是代码。现在立刻给我写一份完整的测试列表。”
结果: AI 会急于冲向终点。它找到了你想要的大部分正确的“风味”(场景),但过程有点混乱。它会重复编写相同的测试(重复项),有时还会发明一些奇怪且没必要的测试。这就像一位大厨做了 20 份汤样,但其中 10 份竟然是一模一样的。
仅构思(“头脑风暴”法):
提示词: “先不要写代码。先告诉我你应该写哪些类型的测试。给我一个想法清单。”
结果: AI 表现得像一个富有创造力的头脑风暴伙伴。它能提出最多关于原食谱中没有提到的、新颖且有趣的创意。然而,它并没有实际“下厨”(编写代码),所以你必须亲自动手将这些想法转化为真正的测试。
先构思后实现(“先计划再行动”法):
提示词: “首先,思考测试的想法。然后,利用这些具体的想法来编写实际的代码。”
结果: 这是最有条理的方法。AI 在行动之前会先停下来思考。它生成的测试列表更精简、更干净,重复项非常少。这就像一位大厨先写好购物清单,检查一遍,然后只烹饪真正需要的食材。
关键发现(味觉测试结果)
找回“金标准”: 当被要求“直接做”(直接实现)时,AI 找到了你原有的绝大部分测试场景。但它很混乱。当被强制要求“先计划”(先构思后实现)时,它变得更整洁了,但漏掉了一些原始场景。
类比: 如果你要求 AI 从一个罐子里找出所有的红弹珠,“直接做”的方法能找到几乎所有的红弹珠,但也顺带抓了一堆蓝弹珠。而“先计划”的方法抓到的红弹珠较少,但没有抓错任何蓝弹珠。
“新”创意: “仅构思”(头脑风暴)法最擅长发现那些不在你原食谱中的新 场景。有时,这些新想法非常有价值——它们捕捉到了原始测试遗漏的漏洞(Bug)。但通常情况下,它们只是对你已知事物的微小变体。
“损坏”的测试: 一些 AI 生成的测试无法运行。研究人员仔细观察了失败的原因。
大多数失败都很简单: AI 猜错了数字(例如,“我认为答案是 5”,但实际上是 4)。这些很容易修复。
有些失败很深层: AI 从根本上误解了代码的工作原理(例如,认为门是开着的,但实际上是锁着的)。这些很难修复,因为 AI 的逻辑本身就是错的。
核心结论
并没有一种单一的“完美”方式来要求 AI 编写测试。这取决于你的需求:
如果你想捕捉到原团队想到的所有内容 ,哪怕过程很混乱,请使用直接实现 。
如果你想要一个精简、高效的列表 且没有重复项,请使用先构思后实现 。
如果你想发现你尚未想到的、具有创造性的新想法 ,请使用仅构思 (然后挑选出最好的部分进行构建)。
研究结论指出,通过观察测试背后的“想法”(场景)而非仅仅看代码本身,开发者可以做出更明智的选择,从而更好地将 AI 应用于工作中。
技术摘要:当生成式 AI 编写测试用例时
问题陈述
软件开发人员越来越多地依赖生成式 AI (GenAI) 来生成单元测试,以减轻手动创建测试的繁琐工作。然而,该领域缺乏稳健的手段来比较不同的人机交互策略的有效性。常见的评估指标(如代码覆盖率或 pass@k)对测试套件的行为 有效性提供的洞察有限。它们无法捕捉实际执行了哪些更高层级的测试场景、场景是否重复,或者 AI 是否引入了新颖且有价值的边缘情况。此外,虽然存在迭代方法,但目前对于将测试用例的构思 (决定测试什么)与实现 (编写代码)分离如何影响生成的测试套件的质量和组成,仍缺乏深入理解。
方法论
作者提出了一种场景驱动的评估方法论 ,用于将自动生成的测试套件与人工编写的测试套件进行比较。研究重点关注了从三个不同来源(Apache Commons Lang3 [工业级库]、HumanEval [精选基准测试] 和 SF110 [SourceForge 项目])中选出的 15 个 Java 方法。选择这些方法是因为它们具有一定的循环复杂度(≥8)、可测试性,并且拥有现有的手动测试套件。
实验设计
本研究通过评估三种不同的提示策略,来考察人类与 AI 在构思与实现方面的分工情况:
直接实现 (C1): AI 在单个提示词中同时生成测试构思和代码。
仅构思 (C2): AI 仅生成测试场景列表(纯文本),不生成实现代码。
先构思后实现: 一个两步走的过程,AI 先生成场景,然后利用这些场景生成完整的测试代码。
针对这 15 个方法中的每一个,使用 GPT-4o 对每种策略进行了三次独立运行,共计生成了 135 个测试套件和超过 1,800 个测试用例。
评估指标
作者并未仅仅依赖结构化指标,而是从手动测试套件中提取语义测试场景 ,将其作为行为预言(behavioral oracle)。他们将一个场景定义为一个具有行为差异性的断言(意图、前提条件、预期结果)。评估通过以下方式将生成的套件与这些手动场景进行对比:
匹配率 (Match Rate, MR): 原有手动场景被 AI 恢复的比例 (M / O M/O M / O )。
保真度 (Fidelity Rate, FR): 生成的场景中对应于原始手动场景的比例 (M / G M/G M / G )。
复现率 (Reproduction Rate, RR): MR 和 FR 的调和平均数,作为衡量生成的套件在多大程度上接近手动套件的综合指标。
重复与新颖性: 计算重复场景和新场景(即手动套件中不存在的场景)的数量。
变异与分支覆盖率: 分析新场景是否杀死了独特的变异体(mutants)或覆盖了新的分支。
失败分析: 对失败的测试进行分类,以区分简单的预期值不匹配与深层的行为误解。
核心贡献
场景驱动的评估框架: 一种在行为场景层面(而非仅在代码覆盖率层面)评估测试套件的方法论,能够明确识别被恢复的、重复的以及新引入的场景。
提示策略的对比分析: 通过 135 个测试套件,对三种交互策略(直接实现、仅构思、先构思后实现)进行了深入的定量和定性比较。
失败模式的见解: 对失败的测试进行了主题分析,区分了易于修复的错误(例如错误的预期输出)和根本性的行为不匹配。
结果
RQ1:不同来源的场景召回率
匹配率: 三种来源(Apache、HumanEval、SF110)的匹配率大致相当。
保真度与复现率: Apache 方法的保真度 (FR) 和复现率 (RR) 显著高于 HumanEval 和 SF110。这表明对于 Apache 方法,生成场景中对应于现有手动场景的比例更大。作者将其归因于 Apache 的手动测试套件规模较大(增加了匹配的基数),以及模型在其训练数据中对广泛使用的库代码具有熟悉度。
总体而言: 没有一种策略能在所有运行中实现完美复制 (MR=1 且 FR=1)。
RQ2:提示策略的影响
直接实现: 生成的测试套件规模最大,匹配场景数量最多(最高 MR),但重复项也最多。它恢复了更多的参考场景,但以牺牲紧凑性为代价。
先构思后实现: 生成的套件最紧凑,总场景数最少,重复项也最少。它提供了一种平衡:在恢复大量场景的同时,在冗余度方面比“直接实现”具有更高的保真度。
仅构思: 生成了最多的新 场景(手动套件中不存在的场景),这表明它是探索测试设计空间并发现潜在边缘情况的最有效策略。
统计显著性: 不同策略之间在重复项和新场景计数方面的差异具有统计学显著性。
RQ3:新场景
GenAI 持续生成了手动套件中未发现的新场景。
价值: 虽然大多数新场景并未显著增加分支覆盖率,但变异分析显示,部分新场景确实杀死了独特的变异体。例如,在 valid date 方法(HumanEval)中,新场景将变异分数从 59% 提高到了 81%。
结论: 新场景通常会扩展所探索的行为空间,即使它们并不总是能转化为即时的结构覆盖率提升。
RQ4:失败的测试
失败原因: 最常见的失败原因是“错误的预期值”(34 例),其次是“对方法行为的错误预期”(12 例)。
可修复性: 许多失败的测试是易于修复的(例如修复一个输出值)。
行为不匹配: 一部分在所有运行中都始终失败的测试,更有可能源于对方法行为的深层误解或不支持的功能,而非简单的计算错误。这些案例突显了规范或假设可能需要澄清的领域。
意义与主张
本文主张,评估 GenAI 生成的测试需要超越结构化指标,转向场景驱动的视角 。研究表明:
提示策略至关重要: 选择何种交互策略会显著改变测试套件规模、重复性和新颖性之间的权衡。
直接实现 最适合最大化已知行为的恢复。
先构思后实现 是生成紧凑、低冗余套件的最优选择。
仅构思 有效用于头脑风暴和发现新的测试场景。
失败的测试具有诊断意义: 失败的测试并非全然负面;它们是信号。简单的误匹配表示代码可修复,而持续的失败则可能揭示开发者对方法行为理解的偏差。
上下文细微差别: GenAI 在测试生成方面的有效性受代码来源(例如对训练数据的熟悉程度)和特定提示策略的影响。
作者总结道,其研究结果为开发者提供了基础,使其能够根据其优先级(是侧重于覆盖率恢复、套件紧凑性,还是探索新的边缘情况)来做出明智的决策,从而将 GenAI 有效地集成到其测试工作流中。
每周获取最佳 computer science 论文。
受到斯坦福、剑桥和法国科学院研究人员的信赖。
请查收邮箱确认订阅。
出了点问题,再试一次?
无垃圾邮件,随时退订。