Industry & PracticeResearch & Benchmarks
利用 大 语言 模型 增强 面向 自然 语言 处理 库 的 自动 化 单元 测试 生成 (上 篇)
以 EvoSuite 为代表的自动化单元测试生成工具在通用软件上表现良好,但面对自然语言处理(NLP)库这类领域特定软件时常常力不从心:输入必须满足语义、句法与结构约束。大语言模型(LLM)能够生成与领域相关的测试代码,
In this piece
利用大语言模型增强面向自然语言处理库的自动化单元测试生成(中文全译·上篇)
本文超长,分上下两篇。下篇:https://openqa.cn/articles/nlp-library-unit-tests-zh-part2
翻译说明:本文是 arXiv 论文 Enhancing Automated Unit Test Generation for NLP Libraries Using Large Language Models(arXiv:2609.14784)的中文全译,由智测团队翻译。原作者:Amirhossein Deljouyi、Annibale Panichella、Andy Zaidman(代尔夫特理工大学,荷兰代尔夫特)。原文以 CC BY 4.0 许可发布。译文保留原文全部章节、数据与结论;参考文献列表从略。
Amirhossein Deljouyi 电子邮箱:a.deljouyi@tudelft.nl 单位:代尔夫特理工大学(Delft University of Technology),荷兰代尔夫特
Annibale Panichella 电子邮箱:a.panichella@tudelft.nl 单位:代尔夫特理工大学(Delft University of Technology),荷兰代尔夫特
Andy Zaidman 电子邮箱:a.e.zaidman@tudelft.nl 单位:代尔夫特理工大学(Delft University of Technology),荷兰代尔夫特
CCS:软件及其工程;软件测试与调试
关键词:自动化测试生成、大语言模型、单元测试、基于搜索的算法
摘要
以 EvoSuite 为代表的自动化单元测试生成工具在通用软件上表现良好,但面对自然语言处理(NLP)库这类领域特定软件时常常力不从心:输入必须满足语义、句法与结构约束。大语言模型(LLM)能够生成与领域相关的测试代码,但仅由 LLM 产出的测试往往无法编译,或覆盖率不足。
我们提出 LLMSuite,一种混合测试生成框架:把自我精炼提示与类级 LLM 推理嵌入基于搜索的测试过程。在该机制中,LLM 依据先前各轮生成的反馈迭代改进测试片段,从而产出越来越精确、与领域一致的代码片段,引导进化搜索去执行复杂、否则难以到达的行为。当底层进化算法在连续多代中没有任何目标得到改进时,这些经过精炼的片段会被解析并注入 EvoSuite 的种群,以扩展搜索空间。
为支撑评估,我们构建了一个新数据集,包含从五个广泛使用的 Java NLP 项目中抽取的 100 个类。我们还用 Java 重新实现了近期的混合 SBST–LLM 技术 CodaMOSA,以便直接比较。在该数据集上,相对 CodaMosa-J,LLMSuite 的分支覆盖率与行覆盖率分别提高约 10% 与 8%,变异得分高出 11%。相对 EvoSuite,LLMSuite 的分支覆盖率与行覆盖率大约高出 15%,变异得分高出 5%。相对仅使用 LLM 的基线,结构覆盖率提高 36%,变异得分提高约 24.7 个百分点。最后,LLMSuite 能够补充人工编写的测试套件,执行那些常常未被测试的领域特定行为。
1. 引言
在当今由软件驱动的世界中,保证软件的可靠性与正确性至关重要(Ko 等,2014;Aniche 等,2019)。因此,自动化(单元)测试已成为软件工程师交付高质量软件的基本实践(Beck,2003;Khatami 与 Zaidman,2024;Khatami 与 Zaidman,2023)。然而,编写测试是一项枯燥且耗时的工作(Beller 等,2019;Aniche 等,2022)。为减轻这一负担,已有多种自动化测试生成技术被提出(Ali 等,2010;Baresi 与 Miraz,2010;Fraser 与 Arcuri,2011;Fraser 等,2015;Derakhshanfar 等,2023;Brandt 等,2024)。该领域的代表性工具包括 Randoop(Pacheco 与 Ernst,2007)和 EvoSuite(Fraser 与 Arcuri,2011)。例如,EvoSuite 是一种基于搜索的软件测试(SBST)工具,利用进化算法创建测试套件(Fraser 与 Arcuri,2015b),并在代码覆盖率(Fraser 与 Arcuri,2013b;Panichella 等,2018a)、发现软件缺陷(Shamshiri 等,2015;Fraser 与 Arcuri,2015a)以及辅助开发者调试(Panichella 等,2016)方面表现出较强能力。
尽管这些工具对通用软件有效,其在自然语言处理(NLP)与机器学习(ML)库等专门领域中的适用性在很大程度上仍未被探索(Wang 等,2021)。鉴于 ML 组件越来越多地用于安全关键系统(如自动驾驶车辆(Gambi 等,2019)和法律文书流水线(Adedjouma 等,2014)),这一空白尤其令人担忧。NLP 库是命名实体识别、情感分析与文本分类等任务的核心,并被嵌入 Hugging Face Transformers 等广泛使用的框架。这些库在结构、输入预期与行为上与传统软件显著不同(Pauzi 与 Capiluppi,2023)。因此,现有测试生成工具在这些场景中往往无法产出有效测试用例(Wang 等,2021)。
启发性示例。 考虑斯坦福 CoreNLP 中的 MorphaAnnotator 类(见代码清单 1;源码位于 https://github.com/stanfordnlp/CoreNLP/blob/v4.5.7/src/edu/stanford/nlp/pipeline/MorphaAnnotator.java),它处理诸如 gave_up 之类的短语动词。这些情形需要能够区分动词成分的特定标注。EvoSuite 无法生成测试用例,原因在于:(1)构造所需对象很困难;(2)缺乏对领域特定输入格式的感知;(3)无法组合多种相关输入属性。因此,这类场景需要能够感知领域特定约束的方法。
大语言模型在代码与自然语言两方面都展现出很强的生成能力(Schäfer 等,2024;Yu 等,2023;Mastropaolo 等,2021;Liventsev 等,2023;Wang 等,2023)。然而,它们为复杂系统生成高覆盖率、可编译单元测试的能力仍然有限(El Haji 等,2024;Siddiq 等,2024;Abdullin 等,2025)。相比之下,SBST 工具擅长系统性地探索执行路径,但缺乏语义与上下文理解(Abdullin 等,2025)。这些局限共同揭示了一种互补式混合方法的机会。
本研究的目标是理解:在 NLP 库这一输入必须满足严格语言与结构不变量(例如语法上合式的句子、合法的句法分析树,以及连贯的标注流水线)的场景中,LLM 生成的代码片段在何处、以何种方式贡献最大。
我们提出 LLMSuite,一种把 LLM 集成进 SBST 流水线的混合框架。核心思想是利用两种方法的互补优势:LLM 提供上下文洞见与语义上有意义的输入,SBST 则通过进化搜索保证系统性探索。LLMSuite 采用类级提示,并结合自我精炼策略:LLM 依据先前各轮生成的反馈迭代改进输出。我们假设,这一设计使 LLM 能够生成越来越精确、与领域一致的测试片段,引导 SBST 去执行复杂、否则难以到达的行为。
本研究由以下研究问题引导:
RQ1 LLMSuite 与 CodaMosa-J、单独的 SBST 以及基于 LLM 的方法相比,在 NLP 库上的代码覆盖率与变异得分如何?
RQ1 考察把 LLM 与 SBST 结合是否比单独使用任一技术更能有效地生成测试。为与近期一种混合 LLM–SBST 方法公平比较,我们用 Java 重新实现了 CodaMosa,并与单独的 SBST 及基于 LLM 的基线一并评估。该研究问题考察:把 LLM 生成的片段集成进搜索过程,是否能提高结构覆盖率与变异得分——这正是传统工具在 NLP 与机器学习库场景中常常表现挣扎的方面(Wang 等,2021)。
RQ2 LLMSuite 的各个组成部分如何影响为 NLP 库生成的测试的覆盖率?
RQ2 分析 LLMSuite 的设计选择如何影响覆盖率,例如提示策略、LLM 模型选择、字符串输入的精炼、调用 LLM 测试生成的频率,以及使用不同上下文层级(方法级与类级)。
RQ3 SBST、基于 LLM 的测试与 LLMSuite 在 NLP 库的不同功能类别上表现如何,LLMSuite 又以何种方式补充 SBST?
NLP 库实现了多样化的功能——如分词、词性标注等——各自具有不同的输入约束与结构特征。在 RQ3 中,我们考察 LLM 能否通过生成更贴合特定 NLP 任务、语义更相关且更多样的测试输入,帮助 SBST 克服领域特定挑战与局部最优。我们分析各方法在这些类别上的有效性。
RQ4 LLMSuite 在多大程度上能够补充 NLP 库中人工编写的测试用例?
RQ4 探索 LLMSuite 生成的测试是否覆盖了人工编写测试未执行的场景。
本文的主要贡献如下:
- 我们提出 LLMSuite,一种多模式混合测试生成框架,将 LLM 与 SBST 集成,用于领域特定软件测试。
- 我们首次在领域特定库(聚焦 NLP 软件)的语境下,对混合 SBST/LLM 测试生成方法进行系统评估。
- 我们构建了一个基准,包含从五个广泛使用的 Java NLP 库中抽取的 100 个类,以支持该场景下测试生成器的评估。
- 我们发布了包含实现、基准与结果的公开复现包(LLMSuite,2024)。
// A. 被测方法的一部分
private static String phrasalVerb(Morphology morpha, String word, String tag) {
// must be a verb and contain an underscore
if(!tag.startsWith("VB") || !word.contains("_")) return null;
// check whether the last part is a particle
String[] verb = word.split("_");
if(verb.length != 2) return null;
String particle = verb[1];
if(particles.contains(particle)) {
String base = verb[0];
String lemma = morpha.lemma(base, tag);
return lemma + '_' + particle;
}
return null;
}
// ————————————————————————-
// B. ChatGPT 测试用例
@Test
public void testPhrasalVerbLemmatization() {
MorphaAnnotator annotator = new MorphaAnnotator(false);
CoreLabel token = new CoreLabel();
token.set(TextAnnotation.class, "gave_up");
token.set(PartOfSpeechAnnotation.class, "VBD");
…
annotator.annotate(annotation);
String lemma = token.get(LemmaAnnotation.class);
assertEquals("give_up", lemma);
}图 1. 启发性示例
2. 背景
基于搜索的软件测试。 EvoSuite(Fraser 与 Arcuri,2011)和 Randoop(Pacheco 与 Ernst,2007)等自动化测试生成工具,使用基于搜索或随机的策略从 Java 代码生成测试套件(Fraser 与 Arcuri,2013b;Panichella 等,2018a)。基于搜索的软件测试(SBST)把测试生成表述为优化问题,使用由搜索目标引导的元启发式算法来最大化代码覆盖率(Panichella 等,2018a;Rojas 等,2016)。播种技术注入先验知识(例如被测类中硬编码的常量字符串),可以进一步提高有效性(Rojas 等,2016)。Randoop 使用反馈导向的随机测试,可扩展性良好(Wang 等,2021),但 SBST 通常能获得更高覆盖率,尤其是对难以到达的代码(Panichella 等,2018a)。
自然语言处理库。 自然语言处理(NLP)是人工智能(AI)的一个分支,通过把文本转换为结构化数据,使计算机能够理解并生成人类语言(Collobert 等,2011;Chowdhary,2020;Hirschberg 与 Manning,2015)。NLP 已从基于规则的系统演进到统计模型,并在算力与数据可用性进步的推动下,进一步走向机器学习(ML)与深度学习(DL)(Devlin 等,2019;Zhao 等,2022)。核心任务包括词性标注、命名实体识别、机器翻译与问答(Chowdhary,2020;Devlin 等,2019)。Stanford CoreNLP 与 NLTK 等库为这些任务提供工具与 API,常常使用嵌入或上下文模型(Manning 等,2014;Bird 等,2009)。
大语言模型。 大语言模型(LLM)是基于 Transformer 架构的 AI 系统(Vaswani 等,2023),在海量数据集上训练,以学习文本、代码与对话中的模式(OpenAI: 等,2023)。它们通过自回归的词元预测生成响应。提示设计对 LLM 的有效性起着关键作用。思维链(Chain of Thought,CoT)推理等技术可以提升性能(Wei 等,2023;Li 等,2023b;Marvin 等,2023)。尽管如此,提示构造往往仍然是一项经验性挑战(Zamfirescu-Pereira 等,2023)。
LLM 越来越多地应用于软件工程(Izadi 等,2022;Izadi 等,2024;Al-Kaswan 等,2023),Code Llama(Rozière 等,2023)、StarCoder(Li 等,2023a)、Codex(Chen 等,2021)与 GPT-4(OpenAI: 等,2023)等模型面向代码相关任务进行了定制。近期工作探索它们在单元测试生成中的作用(Schäfer 等,2024;Siddiq 等,2024;Rao 等,2023),或作为基于搜索的测试中的辅助(Lemieux 等,2023),或作为完全自动化手段(Schäfer 等,2024)。Gu 等近期把基于 LLM 的测试生成与静态控制流分析相结合,以处理测试不足的区域(Gu 等,2025)。
3. LLMSuite 方法
图 2 给出 LLMSuite 方法的总览。它由两个主要部分组成:α 搜索过程,以及 β 基于 LLM 的测试生成。LLMSuite 扩展了基于搜索的测试生成框架 EvoSuite(Fraser 与 Arcuri,2011),在生成过程的关键阶段集成 LLM。具体而言,当搜索过程停滞时(图中以紫色标出),会调用 LLM 生成多样化的候选测试用例。额外组件保证 EvoSuite 与 LLM 之间的无缝交互。我们还纳入了自我精炼提示策略(Madaan 等,2023)——该策略最初被证明可在七项任务上把性能提高 20%——并将其改造用于测试生成,以促进生成更多样的测试用例(图中以蓝色标出)。
图 2. LLMSuite 方法总览
LLMSuite 的目标是生成那些用 DynaMOSA(Panichella 等,2018a)等传统基于搜索的技术来产生时颇具挑战或非常耗时的测试用例。预期 LLMSuite 的测试生成在以下场景中具有优势:(1)构造复杂的测试设置;(2)针对边界情形与潜在失效点;(3)生成需要领域特定知识的测试用例,例如 NLP 库。
在我们的方法中,当种群适应度在一定代数内没有改进时(S = 20),我们将其视为停滞点(如图中步骤 1)。此时触发 LLM 测试生成过程,以引入新的测试片段(步骤 2)。这些片段预期带来领域特定知识,帮助使测试池多样化,并引导搜索走出局部最优。为促进多样性,LLM 会以不同目标被多次提示。首先,LLM 测试生成组件生成测试用例的基础(步骤 3),然后将其重构为所需格式(步骤 4),最后加入边界情形,以针对未覆盖或难以到达的场景,从而在覆盖率意义上得到更丰富、更多样的测试用例(步骤 5)。这些生成的测试用例随后被解析为与基于搜索的测试生成兼容的格式(步骤 6),并与现有种群合并(步骤 7)。在后续迭代中,搜索过程可以利用这些新的、已嵌入领域知识的 LLM 生成测试用例,演化出最终到达新分支或执行边界行为的额外测试(步骤 8)。搜索完成后,所有测试用例都会被编译,以确保它们可编译且稳定,即只应因断言违反而失败,而不是因其他问题(例如幻觉代码)而失败。
下面分别说明 LLM 测试生成与搜索过程。
3.1. LLM 测试生成
我们使用 OpenAI 的 GPTx-4o 模型(OpenAI: 等,2023)作为 LLMSuite 测试生成组件的默认 LLM。不过,LLMSuite 采用模块化架构,可以方便地把 LLM 替换为任何其他模型。在第 5.2 节中,我们考察用替代模型替换 ChatGPT 的影响,具体是 Meta 的开源代码模型 code-llama:13b-instruct(Rozière 等,2023),通过 Ollama 框架访问(https://ollama.com/)。
LLMSuite 分三个顺序阶段提示 LLM:(1)生成初始测试类;(2)把生成的测试用例转换为所需格式;(3)精炼测试以捕获额外的边界情形。对每个阶段,我们依据近期提示工程研究中的最佳实践编写了专门提示(Marvin 等,2023;Wei 等,2023;Li 等,2023b;Deljouyi 等,2025)。如代码清单 3 所示,这些准则强调:采用清晰的开发者人设(1);使用可执行且精确的任务指令(2);通过思维链以及针对每项任务的定制指导实现更深的推理(3);以及标准化输入/输出格式(4)。
我们有意把初始测试生成与重构分成不同阶段。这是因为 EvoSuite 支持一种特定的测试用例格式,测试必须自包含——排除循环、外部方法调用或辅助工具等构造。我们的试验表明,把这两个阶段分开在实践中效果更好;若在初始测试生成过程中就强制格式约束,往往会降低 LLM 的创造性并导致违反准则。收到 LLM 的响应后,我们执行后处理步骤,包括使用 ANTLR 进行语法校验,以及自动修复缺少逗号或括号等常见问题。需要说明的是,这些修复发生在基于 LLM 的测试生成阶段、与 EvoSuite 集成之前,不应与随后的搜索过程相混淆。
LLM 测试生成组件从图 2 的步骤 2 开始:它接收被测类或方法,并生成相应测试用例。默认情况下,LLMSuite 使用带类级提示的自我精炼提示策略,从而为 LLM 提供更多上下文。图 4 以 MorphaAnnotator 类说明这一过程:在步骤 I 中,LLM 为词形还原动词 “giving”(标注为 VBG)生成一个初始测试用例。该测试使用两个外部辅助方法——generateToken 与 generateSentence——它们需要在步骤 4 中内联进测试代码,以匹配与 EvoSuite 兼容的格式。在步骤 5 中,我们启动一个自我精炼循环,运行 T 次迭代(默认 T = 5)。在每次迭代 t 中,使用与代码清单 3 类似的提示模板提示 LLM。要求它分析哪些场景尚未被覆盖,然后生成新的边界测试用例来填补这些空白。为使该反馈循环成为可能,我们维护对话历史并将其纳入提示,使 LLM 能够对过去的测试用例进行推理。所有生成的测试都加入共享池,并且只保留基于测试名称判定为唯一的用例。与 Madaan 等的工作(Madaan 等,2023)把反馈与精炼分成两个独立提示不同,我们把它们统一为单一提示,以减少提示次数。在图 4 的步骤 III 中,针对短语动词情形(“give_up”)生成了一个测试用例,作为初始测试用例。
<<SYS>>
You are a (ADJECTIVE) developer focusing on (TASK AT HAND)
<</SYS>>
[INST]
2 Your task is to (TASK) while strictly following the guidelines below:
### Guidelines:
[For self-refinement:]
1. Examine the existing test cases to identify untested scenarios.
2. Clearly list these untested cases.
3. Generate additional test cases to improve coverage, especially targeting
boundary conditions, corner cases, and potential failure points.
### Output format:
Your response should be placed between [TEST] and [/TEST].
### Code to Test:
[CODE]{content}[/CODE]图 3. LLMSuite 的提示模板
图 4. 运行示例
3.2. 搜索过程
EvoSuite 使用由遗传算法引导的基于搜索的方法生成测试用例。在其算法中,DynaMOSA 已展现出较强性能(Panichella 等,2018a;Campos 等,2018;Lukasczyk 等,2023)。然而,搜索可能停滞在局部最优——尤其当测试输入需要领域特定知识时,正如我们的启发性示例所示。为解决这一问题,我们扩展 DynaMOSA,利用 LLM 生成的测试摆脱停滞:当任何一个目标在连续 20 代中都没有改进时——DynaMOSA 使用其多目标优化机制识别这一情形——LLMSuite 调用 LLM 生成新的测试用例。这些 LLM 生成的测试把领域语义注入测试种群——这是搜索本身难以推断的语义知识。该阶段代表领域语义与搜索相遇的关键时刻。虽然受到先前工作(Lemieux 等,2023)的启发,我们的方法在设计与执行上都有实质差异。与 CodaMOSA 不做高级提示工程的一次性查询不同,LLMSuite 通过迭代的自我精炼过程引导 LLM:候选测试依据关于未覆盖场景的反馈被修订;这一类似搜索的机制借鉴自我精炼范式(Madaan 等,2023),能够生成更复杂、与领域一致的输入,使 SBST 可以更有效地加以利用。LLMSuite 还采用类级提示,与 CodaMOSA 的方法级设计形成对比,在减少提示次数的同时,为跨方法交互的推理提供更丰富的上下文。此外,LLMSuite 与 DynaMOSA 集成,并引入定制的解析与校验流水线,支持嵌套调用、可变参数、多维数组、赋值与 mock 语句,从而使 LLMSuite 能够使用大部分 LLM 生成的代码片段。
生成的测试用例由 LLM2EvoSuiteParser 解析为与 EvoSuite 兼容的代码;我们的定制解析器使用 Spoon(Pawlak 等,2016)进行静态分析,并把 LLM 生成的文本代码转换为 EvoSuite 的内部表示。例如,token.set(..., "VBD") 这样的一行会变成对象初始化与方法调用,如 class1 与 coreLabel0.set(...)。解析器支持广泛的构造,包括嵌套调用、可变参数、多维数组与赋值。
当在搜索阶段遇到 EvoSuite 不支持的构造(例如循环、lambda、try-catch 块)时,解析器有选择地提取合法子成分,例如断言中的表达式或 try 块中的语句。它也会尝试跳过幻觉行的错误。例如,若 LLM 生成的测试片段中 token.set(…) 有三个参数,但只有两个合法,解析器通过宽松的参数匹配保留前两个并丢弃其余部分。
解析之后,合法的 LLM 生成测试与当前种群取并集。EvoSuite 在进入下一代之前对种群进行排序与更新。这种 LLM 集成最多可以发生 L 次(默认 L = 5),并且 LLM 生成的测试可以参与交叉与变异等遗传操作。因此,EvoSuite 可以探索它单独无法演化出的测试输入。例如,在图 4 的示例 V 中,短语动词 “give_up” 与另一个标注为 “NN” 的测试交叉,产生一个变体,在代码清单 1 的第 11 行触发异常。这些混合用例表明,把 LLM 生成的内容集成进基于搜索的测试,对获得更广覆盖率是有价值的。
4. 实验设置
本节描述针对第 1 节所引入研究问题的评估方法。
RQ1 LLMSuite 与 CodaMosa-J、单独的 SBST 以及基于 LLM 的方法相比,在 NLP 库上的代码覆盖率、变异得分如何?
RQ2 LLMSuite 的各个组成部分、我们设计中的各个组成部分,如何影响为 NLP 库生成的测试的覆盖率?
RQ3 LLMSuite 的测试在 NLP 库的不同功能类别上表现如何,又以何种方式补充 SBST?
RQ4 LLMSuite 在多大程度上能够补充 NLP 库中人工编写的测试用例?
基线选择。 RQ1 与 RQ3。我们在 RQ1 与 RQ3 中考虑三个比较基线:(1)EvoSuite(Fraser 与 Arcuri,2011),配置为 DynaMOSA 搜索策略(Panichella 等,2018a);(2)LLMOnly,仅由 ChatGPT-4o-latest-2025-07-12(OpenAI: 等,2023)生成的测试用例;(3)CodaMosa-J(Lemieux 等,2023),即我们对该方法的 Java 重新实现。由于原始 CodaMosa 面向 Python,我们尽可能贴近地重新实现了高层算法逻辑,包括巡查过程、对低覆盖测试目标的关注、方法级提示,以及使用 MOSA 作为底层 SBST 策略。不过,若干组件必然与原始实现不同:CodaMosa 的研究使用 OpenAI Codex(Chen 等,2021),而我们使用 ChatGPT-4o-latest,并且我们使用自己的 Java 解析器,替代原先使用的 Python 专用工具。
LLMOnly 的测试用例与 LLMSuite 中使用的类似,但不经过我们的解析器处理。因此,由于解析器在支持某些代码构造上存在局限,该基线可能获得更高的原始覆盖率。
RQ2。对于 RQ2,我们系统分析方法中各个组成部分如何影响测试覆盖率。具体考察:(1)LLM 模型的选择,以及所提供上下文信息的层级(方法级与类级);(2)提示策略,包括是否使用自我精炼;(3)精炼字符串输入的技术;(4)调用基于 LLM 的测试生成的频率。为隔离每个因素的效应,我们设计了四个实验变体,每个变体只修改一个组件,其余保持固定。我们相对于 EvoSuite 与默认 LLMSuite 配置评估每个变体的测试覆盖率。
RQ4。在 RQ4 中,我们比较 LLMSuite 达到的测试覆盖率与人工编写测试用例的覆盖率。该比较仅限于数据集中存在人工编写测试的类子集。
数据集与 NLP 项目。 我们从五个广泛使用的基于 Java 的 NLP 库中收集了 100 个类:CoreNLP(Manning 等,2014)、OpenNLP(OpenNLP,2005)、MALLET(McCallum,2002)、CogCompNLP(Khashabi 等,2018)与 GATE(Cunningham,2002)。表 1 汇总了这些库的关键统计。我们调整了方法与工具,使其兼容 Java 8、11 与 17。
表 1. 实验所用 NLP 库概览
| 项目 | 描述 | 版本 | Java | 类数 |
|---|---|---|---|---|
| CoreNLP(Manning 等,2014) | 功能完整的 NLP 工具包,含句法分析、NER 与共指 | 4.5.7 | 11 | 42 |
| OpenNLP(OpenNLP,2005) | 分词与词性标注等基础 NLP 任务 | 2.3.3 | 17 | 17 |
| Mallet(McCallum,2002) | 文本分类与序列标注 | 2.1.0 | 8 | 16 |
| GATE(Khashabi 等,2018) | 基于规则与基于 ML 的 NLP 流水线 | 9.1.0 | 8 | 11 |
| CogCompNLP(Khashabi 等,2018) | 语义与共指分析工具包 | 4.0.15 | 8 | 14 |
从 NLP 库收集目标类。 为从选定的 NLP 库中收集类,我们遵循若干步骤(过滤、分类与收集、归类),以确保数据集均衡且有代表性。
- 过滤:(1)我们从搜索中滤除所有静态、抽象与私有类。(2)对每个剩余类,计算三项指标:(a)类的加权方法数(WMC);(b)分支数;(c)非静态方法数。这些指标被归一化并合并为单一分数。(3)依据该分数对类排序,并为每个项目选取排名前 50 的类。
- 分类与收集:(1)我们人工查阅其 JavaDoc 文档,依据(Khashabi 等,2018)的分类方案指定功能类别。(2)从该集合中,我们选取共同代表多样化功能的 100 个类。
- 归类: 我们把功能类别归并为更宽的语义类别以便分析。
最后,我们把数据集组织为九个功能类别,见表 2。为减少 RQ2 的运行次数,我们从 100 个目标类中随机选取 60 个。
表 2. NLP 软件中的功能类别
| 类别 | 说明 |
|---|---|
| 共指(Coreference) | 涵盖检测并消解指向同一实体的指代的组件,如提及检测与共指消解 |
| 数据结构(Data Structures) | 包括用于表示文本的核心数据类,例如文档与语料,以及配套的工具函数 |
| 信息抽取(Information Extraction) | 从文本中抽取特定信息的组件——如引语、名称、性别或关系特征——常常基于规则,不依赖外部模型 |
| 语言标注(Linguistic Labeling) | 为文本赋予标签的任务,如 NER、词性标注、情感分析、性别识别与维基化 |
| ML 算法(ML Algorithms) | 分类器与聚类等学习算法,常用于支撑标注与共指模块 |
| 规范化(Normalization) | 涵盖词干提取与词形还原等标准文本规范化过程 |
| 句法分析器(Parser) | 分析文本句法结构的组件——如依存或成分句法分析——并生成支持下游任务的树或图表示 |
| 切分(Segmentation) | 把文本拆成单元,例如分词、句子切分与组块分析 |
| 主题建模(Topic Modeling) | 使用 LDA 等概率模型揭示文本中的潜在主题 |
表 3. 数据集的 NLP 功能类别分布
| 类别 | CoreNLP | OpenNLP | Mallet | Gate | CogCompNLP | 合计 |
|---|---|---|---|---|---|---|
| 共指 | 7 | 0 | 0 | 0 | 1 | 8 |
| 数据结构与工具 | 3 | 0 | 2 | 7 | 1 | 13 |
| 信息抽取 | 5 | 1 | 0 | 0 | 1 | 7 |
| 语言标注 | 9 | 2 | 0 | 0 | 4 | 15 |
| ML 算法 | 0 | 1 | 9 | 1 | 3 | 14 |
| 规范化 | 3 | 5 | 0 | 0 | 1 | 9 |
| 句法分析器 | 8 | 2 | 0 | 3 | 2 | 15 |
| 切分 | 7 | 3 | 0 | 0 | 1 | 11 |
| 主题建模 | 0 | 3 | 5 | 0 | 0 | 8 |
| 合计 | 42 | 17 | 16 | 11 | 14 | 100 |
评估有效性的指标。 为评估给定项目的单元测试套件质量,我们使用代码覆盖率与变异得分。覆盖率方面,我们使用受 EvoSuite 启发的指标,包括指令覆盖率与分支覆盖率。指令覆盖率对应 Java 字节码指令,在源代码层面大致等价于语句覆盖率。分支覆盖率度量每个条件语句的两种结果(真与假)是否都已执行,从而有效覆盖程序控制流图中的边。变异得分方面,我们使用 JUGE(Devroey 等,2023),这是评估 Java 单元测试生成器的基准基础设施,并已广泛用于年度 SBFT 工具竞赛(Jahangirova 与 Terragni,2023;Moon 等,2025)。JUGE 内部使用 PITest(PIT,2025)计算变异得分,量化测试套件检测注入故障(变异体)的能力。我们扩展了 JUGE 以支持 Java 11 与 17,确保与我们的基准兼容。
分析方法。 为在所有目标类上比较 LLMSuite 相对基线工具的测试有效性,我们采用重复测量设计,遵循基于搜索技术的既有评估指南(Arcuri 与 Briand,2014)以及涉及 LLM 的研究(Sallou 等,2024)。每个工具对每个类执行五次,以捕获 LLM 方法与 SBST 方法固有非确定性带来的变异。对于 LLM 组件,我们使用默认温度 1.00(范围 [0, 2])。较低温度使输出更确定,较高温度引入更多随机性。尽管先前工作表明温度与输出质量并不相关(Coignion 等,2024),使用默认值可为评估基于 LLM 的测试生成提供一致且合理的随机性水平。
为在逐类基础上比较各工具,我们应用 Wilcoxon 符号秩检验(α = 0.05),它适用于成对、非正态分布的数据。为在所有被测类(CUT)上把 LLMSuite 与其他基线比较,我们首先对每个指标(分支覆盖率、行覆盖率与变异得分)计算五次运行的中位数,作为代表性性能值。然后使用 Friedman 检验评估各工具的中位数得分是否存在显著差异,随后使用 Conover 事后检验进行成对多重比较。为量化差异幅度,我们计算 Vargha 与 Delaney 的 A₁₂ 效应量(Vargha 与 Delaney,2000),它表示一种方法优于另一种方法的概率。A₁₂ 的解释为:小效应(0.56 ≤ A₁₂ < 0.64)、中等效应(0.64 ≤ A₁₂ < 0.71)与大效应(A₁₂ ≥ 0.71)(Vargha 与 Delaney,2000)。最后,为评估效应量估计的稳健性,我们按 Efron 的自助法(Efron,1992),在逐类 A₁₂ 值上计算 95% 偏差校正自助置信区间(CI)。95% 置信区间给出一个不确定性范围,真实效应量会落在重复抽样的 95% 之中,从而以不依赖分布的方式计入基于 LLM 与基于搜索的测试生成所固有的随机性。对每个类,我们生成数千个自助重抽样并重新计算 A₁₂;最低与最高的自助估计构成 CI 边界。我们通过检查 CI 是否完全位于 0.5 之上(LLMSuite 胜)、完全位于 0.5 之下(基线胜)或跨越 0.5(平局)来判定逐类显著性。
实验协议。 我们以默认参数配置 EvoSuite,这些参数在先前工作中表现良好(Arcuri 与 Fraser,2013)。为给生成高质量测试用例留出更多时间,我们把测试预算(max_time)从 60 秒提高到 900 秒。为确保七个测试生成器——EvoSuite、CodaMosa-J、LLMSuite 及其四个变体——之间的统计比较可靠,我们将每次运行重复五次,共计 3300 次运行((100 × 3 + 60 × 6) × 5),其中 100 个类用 LLMSuite 与 EvoSuite 测试,60 个类用 6 个变体测试,各重复 5 次。实验在配备 64 核 AMD EPYC 处理器与 256 GB 内存的服务器上运行。我们使用 Docker 并行执行,每个容器分配 6 个 CPU 核心与 16 GB 内存。LLMSuite 使用 ChatGPT-4o-latest-2025-07-12(https://platform.openai.com/docs/models/chatgpt-4o-latest)作为主要 LLM(见第 3.1 节)。为评估模型选择的影响,我们还在 NVIDIA L40S GPU 上运行了 code-llama:13b-instruct(Rozière 等,2023)。
人工分析。 对于 RQ3 与 RQ4,我们对手工测试覆盖率进行了人工分析。对于 RQ3,我们考察 EvoSuite 与 LLMSuite 之间覆盖率差异显著、且跨越多种 NLP 功能的类。通过识别每个类中被一种方法覆盖但被另一种方法遗漏的部分,我们获得它们在不同 NLP 任务上相对优势与局限的洞见。对于 RQ4,我们分析了 27 个既有人工编写测试用例、又属于我们数据集的类。对这些类,我们首先计算人工编写测试、LLMSuite 及其组合的分支覆盖率与变异得分。然后识别人工测试与 LLMSuite 都未覆盖的代码块,并调查这些缺口的根本原因。由于数据集并不很大,没有必要引入多名编码者。相反,我们遵循 Hoda 对单分析者研究的指导(Hoda,2025,第 260 页)。主要分析者进行编码,新出现的编码与解释定期与其他研究者一起审阅,以确保一致性,并在需要时改进分析。
图 5. LLMSuite 与基线工具的测试有效性比较。(a)分支覆盖率,(b)行覆盖率,(c)所有类上的变异得分分布,以箱线图展示。(d–f)逐类覆盖率散点图,比较 LLMSuite(纵轴)与各基线(横轴):EvoSuite(d)、LLMOnly(e)与 CodaMosa-J(f)。对角线上的点表示覆盖率相同,对角线上方的点表示 LLMSuite 覆盖率更高的类,对角线下方的点表示基线获胜。
下篇继续:利用大语言模型增强面向自然语言处理库的自动化单元测试生成(下)。
Found it useful? Pass it on
Scan with WeChat to open it on your phone and forward it.