Automated Generation of Issue-Reproducing Tests by Combining LLMs and Search-Based Testing

本文提出了结合大语言模型与基于搜索的软件测试技术的 BLAST 工具,用于从问题 - 补丁对中自动生成复现问题的测试用例,并在基准测试和 GitHub 实际部署中验证了其优于现有技术的性能及实用价值。

Konstantinos Kitsios, Marco Castelluccio, Alberto Bacchelli

发布于 2026-03-11
📖 1 分钟阅读☕ 轻松阅读

Each language version is independently generated for its own context, not a direct translation.

这篇论文介绍了一个名为 BLAST 的新工具,它的任务是自动帮程序员写“捉虫测试”

为了让你更容易理解,我们可以把软件开发想象成开一家新餐厅,把“软件漏洞(Bug)”想象成一道难吃的菜,把“补丁(Patch)”想象成厨师修改后的新食谱

1. 核心问题:为什么需要“捉虫测试”?

在餐厅里,如果顾客投诉“这道菜太咸了”(这是Issue/问题),厨师会调整配方(这是Patch/补丁)。

但是,光改配方还不够。厨师需要做一个**“试吃测试”**:

  1. 旧配方做这道菜,尝一口,确认它确实太咸了(证明问题存在)。
  2. 新配方做这道菜,尝一口,确认它现在味道完美(证明问题解决了)。

这个“试吃测试”就是Issue-Reproducing Test(问题复现测试)。有了它,餐厅老板(开发者)才敢放心地把新菜端给下一位顾客,而且以后万一有人又不小心把盐放多了,这个测试会立刻报警,防止问题重演。

痛点是: 写这个测试很麻烦,很多厨师(程序员)在忙完改配方后,就忘了写这个测试,或者觉得太累直接跳过。这就留下了隐患。

2. 以前的尝试:为什么不够好?

以前,研究人员尝试用两种方法自动写这个测试:

  • 方法 A:大语言模型(LLM)—— 像一位“博学但爱幻想的实习生”

    • 优点: 它读过很多菜谱,能根据顾客的投诉(Issue)直接写出测试步骤。
    • 缺点: 它有时候会**“幻觉”**。比如,它可能会写:“请调用一个不存在的‘魔法调味瓶’",或者“把盐倒进杯子里”(但代码里根本没有杯子)。它写的测试经常因为语法错误或逻辑不通而跑不起来。
  • 方法 B:基于搜索的测试(SBST)—— 像一位“机械但不知疲倦的试吃员”

    • 优点: 它非常严谨,只会写语法正确、能跑通的测试。它通过不断尝试(像遗传算法一样变异),直到找到能覆盖所有情况的测试。
    • 缺点: 它是个“瞎子”。它不知道顾客投诉的是“太咸”还是“太辣”。它只能盲目地试吃,很难精准地复现那个特定的“太咸”的问题。

3. BLAST 的解决方案:强强联手

BLAST 就像是一个超级主厨团队,它把“爱幻想的实习生”(LLM)和“机械的试吃员”(SBST)结合在了一起,让它们互相配合。

第一步:给实习生(LLM)找帮手

BLAST 不会只把“太咸了”这句话丢给实习生。它会先做三件事:

  1. 查历史: 看看以前类似的菜是怎么做的(Git 历史分析)。
  2. 看上下文: 看看这道菜是用什么锅、什么火做的(静态分析,获取代码上下文)。
  3. 先让试吃员跑一圈: 让机械试吃员(SBST)先试着跑一遍,生成一些语法正确、能跑通的测试代码。

然后,BLAST 把这些“正确的代码片段”和“详细的背景资料”一起喂给实习生。

  • 效果: 实习生不再瞎编乱造了,因为它手里有“标准答案”的片段可以参考。它写的测试既符合语法,又紧扣问题。

第二步:给试吃员(SBST)指方向

反过来,BLAST 也会利用实习生。

  1. 实习生根据问题描述,写了一个**“种子测试”**(Seed),比如:“请尝一下这道菜,如果盐超过 5 克就报错”。
  2. 但是,这个种子可能格式不对,机械试吃员看不懂。
  3. BLAST 有一个**“翻译官”**(中间件),把实习生的“人话”翻译成机械试吃员能听懂的“机器语言”。
  4. 机械试吃员拿着这个种子开始疯狂变异,最终生成一个能精准复现“太咸”问题的测试。

4. 实战演练:GitHub 机器人

为了验证 BLAST 是不是真的有用,作者们没有只在实验室里跑数据,而是真的在 GitHub 上部署了一个机器人

  • 场景: 当有人提交一个新的代码修改(Pull Request)时,机器人会立刻跳出来。
  • 动作: 机器人检查这个修改是否解决了某个问题。如果是,它就启动 BLAST 团队,尝试自动生成那个“捉虫测试”。
  • 结果: 如果生成了测试,机器人就会在代码审查区留言:“嘿,我帮你写了一个测试,你看行不行?”

实验结果:

  • 历史数据(过去的 426 个案例)中,BLAST 成功生成了 35.4% 的有效测试,比目前最好的方法(23.5%)高出一大截。
  • 真实世界(3 个月,32 个真实的代码修改)中,BLAST 生成了 11 个测试。程序员们觉得其中 6 个 是有用的,甚至有两个直接被合并进了代码库!

5. 总结与启示

这篇论文告诉我们:

  1. 单打独斗不行: 光靠 AI(LLM)容易犯傻,光靠传统工具(SBST)太盲目。
  2. 组合拳威力大: 让 AI 提供“思路”和“种子”,让传统工具负责“验证”和“执行”,效果最好。
  3. 真实世界很复杂: 虽然实验室数据很好,但在真实项目中,有些问题确实不需要测试(比如只是改了个名字),或者测试写得不够完美(比如 Mock 太多)。这需要工具更聪明,也需要人类开发者更多的反馈。

一句话总结:
BLAST 就像是一个懂技术的“双核”助手,它既能让 AI 发挥创意,又能让传统工具保证严谨,从而自动帮程序员写出那些能防止 Bug 死灰复燃的“安全网”(测试代码)。