智测 OpenQA

行业与实践研究与基准测试

上下文至关重要:提升基于大语言模型的单元测试生成的实用可靠性(下篇)

智测团队 · OpenQA(openqa.cn)阅读约 26 分钟

上下文至关重要:提升基于大语言模型的单元测试生成的实用可靠性(下)(中文全译)

本文目录

上下文至关重要:提升基于大语言模型的单元测试生成的实用可靠性(下)(中文全译)

上篇:https://openqa.cn/articles/context-matters-unit-tests-zh本篇从「## 4. 工业评估」继续。

4. 工业评估

4.1. 实验设计

工业基准。

表 1. 评估数据集统计。

场景被测方法数复杂依赖占比(%)平均依赖文件数
服务编排规则4334.881.05
数据访问持久化3878.954.13
配置依赖装配1258.333.42
框架入口4252.383.36
数据转换映射1650.003.81
集合流处理1154.552.45
共享工具库1266.673.17
微服务集成基础设施9100.005.44
合计18357.383.05

为使评估反映我们在生产设定中遇到的挑战,我们与工业伙伴密切合作构建该基准,捕捉在真实仓库中部署 LLM 生成测试时所观察到的失败模式。在这些代码库中,被测方法很少是自包含的。其行为往往由依赖注入与配置装配、分布在文件与模块之间的契约,以及由框架管理的执行路径所塑造,正确性取决于约定与隐式资源。我们还看到许多具有非线性控制流与数据流的方法,例如嵌套条件、提前返回与链式变换,其中有意义的分支很难用简单的快乐路径输入到达。当周围上下文缺失或仅被部分推断时,生成的测试往往要么无法编译,要么 mock 设置不一致,要么能够运行但几乎没有行使预期行为。这些观察说明,我们在本基准中把编译成功与成本稳定性视为一等关注点,而不是次要指标。

为捕捉这些实践现实,我们与工业伙伴的工程师一起,使用正在积极维护并已部署到生产的内部 Java 项目来整理基准。这些项目跨越多个架构层,包括核心服务逻辑、数据访问代码、配置与装配组件、Web 控制器、共享工具以及微服务基础设施。我们使用项目级比例分层抽样,以同时反映规模与多样性,并有意把选择偏向具有深层调用链、跨模块交互以及框架管理资源的困难方法。

基准共计 183 个被测方法(表 1):57.38% 具有复杂依赖,平均 3.05 个依赖文件。我们把被测方法所调用的不同外部类与方法计为一种面向耦合的代理指标,与对象间耦合(CBO)对齐(Chidamber and Kemerer, 1994),并把不少于 3 个此类依赖视为复杂依赖,以反映我们的部署中频繁出现编译失败的、依赖沉重的情形。微服务集成基础设施场景是最难的子集(100%;平均 5.44 个文件)。

对比技术。 为展示所提工作流的有效性,我们全面采用六种有代表性或先进的测试生成技术作为基线:

  • EvoSuite(Fraser and Arcuri, 2011)。一种传统的基于搜索的工具,通过进化算法生成 JUnit 测试;它迭代执行并变异候选测试,以最大化结构覆盖率(例如行覆盖与分支覆盖),不使用 LLM。
  • ChatTester(Yuan et al., 2024)。它包含初始测试生成器与迭代测试精炼器。初始测试生成器先利用 LLM 理解被测方法并生成测试,精炼器再迭代修复编译错误。
  • ChatUniTest(Chen et al., 2024)。它以被测方法以及通过预定义规则抽取的上下文为输入,使用 LLM 生成单元测试。对执行失败的测试,它利用 JVM 错误报告引导 LLM 进行纠正。
  • HITS(Wang et al., 2024b)。它先把被测方法分解为切片,并为每个切片创建旨在覆盖全部行与分支的单元测试。这些单元测试共同构成初始测试套件。对不可执行的测试套件,HITS 包含一个修复器加以修复。
  • TELPA(Yang et al., 2024a)。它用程序分析增强基于 LLM 的测试生成,以针对未覆盖分支。TELPA 抽取对象构造序列与和分支相关的依赖,并用覆盖率反馈迭代引导 LLM。
  • RATester(Yin et al., 2025)。它通过向语言服务器查询符号定义与用法来提高仓库感知能力。检索到的全局上下文被注入提示,以减少幻觉与签名不匹配。

对所有基于 LLM 的基线,我们使用其公开可得的开源实现。由于部分原始研究用专有模型实例化其方法,我们把所有 LLM 调用统一到同一组开源模型,以保证公平比较。凡涉及 LLM 之处都一致应用这一标准化,包括单元测试生成以及后续修复步骤。RATester 最初面向 Go 实现。为保持一致的基于 Java 的评估环境,我们遵循作者的 Java 适配并相应重新实现 RATester,而不修改其底层算法设计。

评估指标。 我们使用四项常用指标评估 CATGen 与基线的性能:编译成功率(CSR)、行覆盖率(CovL)、分支覆盖率(CovB)与通过率(PR)。CSR 由成功编译的测试方法数与为所有被测方法生成的测试方法总数之比确定。CovL 计算为已覆盖行数除以源代码中可执行行的总数,CovB 定义为已覆盖分支数除以控制流图中的分支总数。PR 对该指标做了改写,以通过执行的测试方法数作为分子。为公平比较,要求 CATGen 与所有基线各生成一个测试类,但该类中允许多个测试方法。对每个成功编译并执行的测试类,我们使用 JaCoCo 工具(https://github.com/jacoco/jacoco)测量其行覆盖率与分支覆盖率。

实现与环境。 CATGen 用 Java 实现。对于程序结构分析,它使用 IntelliJ PSI 中的 PsiMethod 解析 AST,从而精确抽取方法签名、控制流依赖与文件间关系。该工作流只依赖 AST 级事实;任何提供相同结构信号的合规抽取器都可以替代。上下文感知的骨架构造组件为 JUnit 4 / 5、Spock 与 Spring Boot Test 采用标准化模板,并以 Mockito 与 PowerMock 进行 mock。

从工程角度看,我们的目标是在实际可部署的开源 LLM 下评估 CATGen,而不是穷尽评测所有可用模型。因此我们选择满足以下条件的模型家族:(i)公开可获取且可复现;(ii)提供适合交互式代码生成的指令微调检查点;(iii)在多种参数规模上覆盖通用模型与代码专用变体。我们评估来自 Llama、DeepSeek 与 Qwen 家族的模型,跨越通用模型与代码专用模型以及多种规模:CodeLlama-7B(CL-7B)(AI, 2023)、Llama3.1-8B(Lla-8B)(AI, 2025)、DeepSeekCoder-6.7B-Instruct(DC-7B)(deepseek-ai, 2023)、DeepSeekCoder-33B-Instruct(DC-33B)(deepseek-ai, 2024a)、DeepSeek-R1-Distill-Llama-8B(DRL-8B)(deepseek-ai, 2024b)、DeepSeek-R1-Distill-Qwen-32B(DRQ-32B)(deepseek-ai, 2024c)、Qwen2.5-Coder-7B-Instruct(QC-7B)(Qwen, 2024c)、Qwen2.5-Coder-32B-Instruct(QC-32B)(Qwen, 2024b)以及 Qwen2.5-32B(Q-32B)(Qwen, 2024a)。

CATGen 部署在混合执行环境中,包括 4 块 NVIDIA A100-PCIE-40GB GPU(驱动版本 535.161.08,CUDA 12.2)以及一颗 Intel Xeon Gold 6330 CPU。软件栈包括 JDK 11.0.8、Gradle 7.4 与 Maven 3.3.9,用于管理 Java 模块,并集成 JaCoCo 0.8.11 进行代码覆盖率分析。与 LLM 相关的任务使用 Python 3.10.12,LLM 推理使用 vLLM 0.8.4(Zhang et al., 2023)以实现高效、可扩展的部署。所有实验使用温度为 0 的设置,以保证输出确定。对 EvoSuite 基线,我们为每个被测方法分配 300 秒的搜索预算(Fraser and Arcuri, 2011)。

4.2. 评估结果

I. CATGen 在工业设定中的有效性。 为缓解 LLM 操作中的随机性并保证结果可靠,我们以相同配置独立运行所有基于 LLM 的测试生成过程五次,并以每个方法的平均值作为各指标的最终结果。为评估所观察到的改进的稳健性,我们在对五次重复取平均之后,对成对的逐方法结果使用 Wilcoxon 符号秩检验(Woolson, 2007)。

表 2. 不同模型与不同方法之间的有效性比较。

指标方法平均CL-7BLla-8BDRL-8BQC-7BQC-32BQ-32BDRQ-32BDC-7BDC-33B
CSREvoSuite75.80%N/AN/AN/AN/AN/AN/AN/AN/AN/A
CSRChatTester55.88%29.17%4.60%32.62%66.92%73.03%62.37%75.00%79.23%80.00%
CSRChatUniTest51.70%32.92%5.41%33.50%63.53%71.06%46.09%71.26%70.04%71.48%
CSRHITS51.02%12.61%10.01%27.31%58.93%67.68%61.83%67.95%74.60%78.22%
CSRTELPA64.11%45.72%18.94%41.67%71.45%78.32%74.88%80.14%82.96%82.94%
CSRRATester67.11%50.83%22.37%45.94%75.36%80.45%78.12%83.27%81.14%86.55%
CSRCATGen91.83%90.20%82.73%84.26%92.18%95.61%95.33%96.28%94.91%94.97%
CovLEvoSuite39.55%N/AN/AN/AN/AN/AN/AN/AN/AN/A
CovLChatTester30.76%17.19%2.51%13.92%40.10%48.20%36.76%43.27%36.93%37.97%
CovLChatUniTest29.77%24.75%3.82%12.99%35.51%45.92%39.50%46.91%29.19%29.35%
CovLHITS36.10%32.89%5.72%18.75%42.24%54.47%43.89%46.67%36.35%43.95%
CovLTELPA45.99%41.20%12.35%27.64%53.83%60.48%57.31%58.94%49.18%53.02%
CovLRATester48.43%45.73%15.48%30.52%49.36%62.47%59.81%63.87%52.96%55.68%
CovLCATGen70.10%69.14%57.02%63.60%71.05%75.79%71.68%75.49%73.15%74.01%
CovBEvoSuite34.56%N/AN/AN/AN/AN/AN/AN/AN/AN/A
CovBChatTester29.75%10.20%2.52%13.16%45.67%49.60%32.00%47.88%32.18%34.58%
CovBChatUniTest26.74%14.92%3.25%10.20%31.51%46.78%31.47%49.14%27.49%25.93%
CovBHITS36.33%16.61%5.12%12.27%50.51%56.45%48.02%57.44%39.48%41.04%
CovBTELPA44.32%28.45%10.32%25.78%56.14%62.83%55.81%60.92%48.36%50.27%
CovBRATester46.33%31.67%12.74%24.85%59.32%59.54%58.69%65.12%51.44%53.61%
CovBCATGen63.92%62.13%47.56%52.26%66.54%73.73%63.44%70.27%69.32%70.06%
PREvoSuite44.21%N/AN/AN/AN/AN/AN/AN/AN/AN/A
PRChatTester35.85%29.27%2.27%16.88%46.42%51.57%39.19%52.93%40.32%43.78%
PRChatUniTest30.24%14.22%3.41%11.01%33.54%45.96%31.01%52.72%36.96%43.33%
PRHITS32.93%11.67%3.01%16.50%35.17%46.55%48.74%51.53%38.12%45.07%
PRTELPA39.91%25.48%12.92%22.87%41.93%52.41%49.88%56.32%47.05%50.36%
PRRATester41.71%29.76%10.21%25.34%42.25%55.93%54.32%54.12%49.87%53.61%
PRCATGen54.63%47.00%34.71%37.62%50.54%67.77%64.53%69.36%58.34%61.77%

发现 I:CATGen 显著提高可执行性,同时在工业场景中也比现有方法提供更高的结构覆盖率。 根据我们的经验,工业项目中的一项关键要求是:生成的测试能否在项目特定配置下可靠编译并执行,因为这直接决定测试能够有意义地行使并验证多少行为。如表 2 所示,在编译成功率上,CATGen 达到 91.83%,EvoSuite 达到 75.80%,基于 LLM 的基线中 ChatTester 为 55.88%、ChatUniTest 为 51.70%、HITS 为 51.02%、TELPA 为 64.11%、RATester 为 67.11%。EvoSuite 偶尔会在高度耦合的被测方法上耗尽预算而未发出测试,我们将其计为编译失败,这也部分解释了其较低的编译成功率(Fraser and Arcuri, 2011)。在覆盖率上,CATGen 的行覆盖率达到 70.10%,分支覆盖率达到 63.92%。RATester 分别为 48.43% 与 46.33%,TELPA 为 45.99% 与 44.32%,EvoSuite 为 39.55% 与 34.56%。ChatTester 为 30.76% 与 29.75%,ChatUniTest 为 29.77% 与 26.74%,HITS 为 36.10% 与 36.33%。在通过率上,CATGen 达到 54.63%,EvoSuite 为 44.21%,RATester 为 41.71%,TELPA 为 39.91%,ChatTester 为 35.85%,HITS 为 32.93%,ChatUniTest 为 30.24%。值得注意的是,在基于 LLM 的基线中,TELPA 与 RATester 往往取得更强的总体结果,这与它们在生成测试时显式纳入更广泛项目上下文与跨文件信息的设计相一致。统计检验结果确认,CATGen 持续优于所有基线,在全部成对比较中,CSR、CovL、CovB 与 PR 的 p 值均 < 0.005。我们报告成对比较的未校正 p 值;鉴于在所有对象上观察到的 p 值持续很小,结果的统计显著性仍然稳健。作为 Wilcoxon 报告的一个示例性成对对比,在 QC-32B 下 CovL 相对 RATester,我们得到 n = 183,W = 1148,p = 0.0026,r = 0.339(中等效应)。

发现 II:CATGen 在不同规模与架构的 LLM 上保证稳健性能,更大的模型可能带来更好的结果。 如表 2 所示,底层 LLM 的选择显著影响所有测试生成方法:更大的模型(例如 32B–33B)持续优于 Lla-8B 等较小模型。在模型家族中,Qwen 变体总体领先:QC-32B 取得最高覆盖率(CovL:75.79%,CovB:73.73%),而 DRQ-32B 取得最佳编译成功率(96.29%)与通过率(62.36%)。DeepSeek 模型紧随其后,而 Llama 家族模型,尤其是 Lla-8B,在基线下表现较差。另一方面,结果表明,在相同规模下,代码专用变体往往优于其通用对应模型。例如,QC-32B 优于 Q-32B,经由基于强化学习的知识蒸馏增强的模型(例如 DRQ-32B)进一步超过其通用对应模型。这些发现强调了领域特定预训练以及基于蒸馏的能力迁移对于生成高质量测试的重要性。重要的是,CATGen 在所有 LLM 配置上保持一致的优势。这种稳健性使其对成本敏感或资源受限的场景尤其有价值。即便使用 DC-7B 这样的 7B 规模模型,CATGen 也在所有模型规模上优于全部基线,在效率与有效性之间提供了有说服力的平衡。

II. CATGen 中各组件的贡献。 我们开展消融研究,以考察每个核心组件(即上下文感知的测试类骨架构造、静态编译错误修复,以及基于程序分析的测试增强)对 CATGen 总体有效性的贡献;基于程序分析的后处理模块通过其两个子组件分别评估。据此,我们构造了 CATGen 的四个变体:

  • “w/o skeleton”(去掉上下文感知的测试类骨架构造):该变体从提示中省略基于规则的测试类骨架,指示 LLM 在没有任何结构指导的情况下从零生成测试代码。
  • “w/o repair”(去掉静态编译错误修复):该变体禁用静态修复阶段,只把基于程序分析的测试增强应用于 LLM 生成的原始测试类。
  • “w/o enhancement”(去掉基于程序分析的测试覆盖率增强):该变体禁用测试覆盖率增强组件,保留测试类骨架构造与静态修复,但排除任何分析驱动的增强。
  • “w/o all”:该变体移除全部三个核心组件,仅依赖标准的基于提示的生成,没有任何额外的后处理或增强。

基于 RQ1 的结果,我们选择 QC-32B 作为消融研究的代表性 LLM,因其行覆盖率更优且编译成功率相对较高,体现了总体有效性。为缓解随机变异,我们将每个实验重复五次,并报告所有评估指标上的平均结果。

表 3. CATGen 与其变体的有效性比较。

方法CSRCovLCovBPR
CATGen95.61%75.79%73.73%57.77%
Δ w/o skeleton-3.04%-16.37%-10.28%-8.86%
Δ w/o repair-16.79%-8.95%-6.22%-8.76%
Δ w/o enhancement-1.96%-10.51%-9.51%-0.13%
Δ w/o all-38.88%-30.63%-24.00%-15.98%

发现 III:CATGen 的每个核心组件在达成框架总体性能方面都承担独特且关键的功能。 表 3 给出 CATGen 与其四个消融变体的有效性比较。首先,去掉上下文感知的测试类骨架构造(“w/o skeleton”)导致性能大幅下降:相对完整版本,行覆盖率(CovL)下降 16.37%,分支覆盖率(CovB)下降 10.28%,编译成功率(CSR)下降 3.04%,通过率(PR)下降 8.86%。这突出了结构化测试类骨架在引导 LLM 方面的关键作用。没有它,模型更容易产生幻觉,无法正确构造类声明、mock 注解或实例化被测类,从而导致不完整或无效的测试类。有趣的是,尽管覆盖率与正确性下降,相对稳定的 CSR 表明,即便缺少初始化,基于程序分析的后处理在保持可编译性方面仍然有效。

其次,去掉静态编译错误修复阶段(“w/o repair”)造成覆盖率的中等下降(CovL:−8.95%,CovB:−6.22%),但 CSR(−16.79%)与 PR(−8.76%)下降陡峭得多。这一差异强调了静态修复在处理 LLM 经常产生的语法与结构错误方面的重要性。由于该变体保留了包括测试增强在内的其他组件,所观察到的下降主要源于可编译性问题,而不是生成工作流的改变。

第三,禁用基于程序分析的增强(“w/o enhancement”)使 CovL 与 CovB 分别下降 10.51% 与 9.51%,与去掉测试类初始化时所观察到的损失相当。然而 CSR 与 PR 大体保持稳定(−1.96% 与 −0.13%),表明生成的测试虽然多样性较低,仍保持语法与语义有效。这验证了增强模块在丰富测试多样性、揭示边界情形行为方面具有重要作用。

最后,完全消融情形(“w/o all”)——移除全部三个组件——造成最严重的退化。CSR 与 CovL 分别下降 38.88% 与 30.06%,大致相当于移除各个组件的累积影响。这些结果强调 CATGen 核心模块的互补角色:测试类骨架保证语法结构,静态修复提高正确性与可编译性,基于程序分析的增强通过有针对性的测试生成提高覆盖率。它们共同构成一个连贯的多阶段框架,显著提高 LLM 生成的单元测试的质量与可靠性。

III. CATGen 的效率。 我们评估两项关键指标,以考察计算效率与资源利用:执行时间(Time)与 token 消耗(Tokens)。这些指标在生成阶段(Gen)、后处理阶段(Post)及其合计(Total)上测量。沿用 RQ2 的设置,我们选择 QC-32B 进行验证,因为它在所评估的 LLM 中取得了最佳总体性能。每个实验重复五次以缓解变异,并报告平均结果。

表 4. CATGen 与基线的效率比较。

方法生成时间生成 Token后处理时间后处理 Token总时间总 Token
EvoSuite10,980s0k0s0k10,980s0k
ChatTester2,805s432k1,666s459k4,471s891k
ChatUniTest1,601s234k2,166s857k3,768s1,091k
HITS2,972s459k2,951s799k5,924s1,258k
TELPA4,386s612k0s0k4,386s612k
RATester5,217s735k0s0k5,217s735k
CATGen1,759s203k77s0k1,836s203k

发现 IV:CATGen 在执行时间与 token 消耗上,于生成阶段与后处理阶段都相对所有基线取得显著效率收益。 表 4 汇总了与效率相关的指标结果。在时间效率上,CATGen 以 1,836 秒完成全流程(生成时间与后处理时间之和),优于 ChatUniTest(3,768 秒,−51.27%)、ChatTester(4,471 秒,−58.93%)与 HITS(5,924 秒,−69.00%)。它也显著优于 TELPA(4,386 秒,−58.13%)与 RATester(5,217 秒,−64.80%),并明显快于传统基线 EvoSuite(10,980 秒,−83.28%)。这些改进源于两项关键设计选择:(1)单轮 LLM 生成策略(1,759 秒),避免了基线所使用的高成本迭代精炼循环;(2)基于程序分析的后处理模块只需 77 秒,比 ChatTester(1,666 秒)、ChatUniTest(2,166 秒)与 HITS(2,951 秒)中由 LLM 驱动的修复阶段快一个数量级以上。相比之下,TELPA 与 RATester 依赖多轮 LLM 生成而没有显式修复阶段,由于反复调用模型而导致高累积延迟;EvoSuite 则把大部分时间花在进化搜索与重复测试执行上,而不是模型推理。

CATGen 总共只消耗 203k token,后处理阶段 token 为零。相对 ChatTester(891k)这代表 77.22% 的减少,相对 HITS(1,258k)减少 83.86%。即便 ChatUniTest 的生成时间相对较快,由于严重依赖基于 LLM 的后处理,仍产生 1,091k token。相对 TELPA(612k)与 RATester(735k),CATGen 也实现了可观的 token 节省,因为它们的多轮生成策略需要显著更多的 LLM 交互。综合来看,这些结果表明,CATGen 把测试生成与依赖 LLM 的后处理分离的解耦架构,使单元测试合成具有确定性、可扩展性与资源效率。这一设计尤其适合工业部署,其中延迟与计算成本是关键约束。

5. 开源软件评估

为评估 CATGen 在工业代码库之外的可泛化性,我们额外在广泛使用的开源基准 Defects4J(Just et al., 2014)上评估它。遵循先前研究(Yang et al., 2025c),我们选择四个有代表性的项目 Chart、Lang、Time 与 Math,它们跨越图表渲染、语言工具、日期时间处理与数值计算等不同领域。

我们复用与工业评估相同的被测方法评估协议、对比技术、指标与实验配置。为在开源软件(OSS)设定中保证受控比较,我们用单一底层模型 Qwen2.5-Coder-32B-Instruct(QC-32B)实例化 CATGen 与所有基于 LLM 的基线,用于全部 LLM 调用。其他所有因素,包括提示、推理设置、编译与执行流水线以及成本核算,都保持相同。这一设置隔离了基准本身的效应,确保所观察到的差异来自数据集特征,而不是实验配置的变化。

为进一步评估缺陷检测能力,我们报告变异分数(MS)——被杀死的变异体与变异体总数之比——它直接评估超出 PR 的缺陷检测有效性。MS 仅在开源基准上报告;由于数据集的专有性质,工业设定中不报告该指标。

表 5. 在 Defects4J 上的有效性。

指标项目EvoSuiteChatTesterChatUniTestHITSTELPARATesterCATGen
CovLChart48.31%54.24%59.10%62.14%64.50%67.53%75.71%
CovLMath60.21%47.89%51.81%54.42%64.56%67.13%73.32%
CovLLang71.32%80.47%79.12%83.52%81.21%80.42%91.32%
CovLTime69.91%71.33%70.21%75.31%76.24%76.31%82.21%
CovBChart43.51%48.14%51.28%60.47%60.74%62.43%72.89%
CovBMath45.17%38.54%40.78%48.21%61.54%54.32%64.74%
CovBLang62.89%74.21%76.32%77.21%80.21%78.21%84.25%
CovBTime60.74%65.33%67.32%69.24%75.87%70.32%80.45%
CSRChart98.21%64.32%71.21%75.41%76.54%80.12%90.45%
CSRMath97.24%59.21%65.78%67.89%70.12%77.32%91.57%
CSRLang100.00%71.54%76.20%82.65%83.41%82.12%94.45%
CSRTime97.21%69.54%70.24%77.54%75.69%80.23%93.14%
PRChart89.45%41.23%59.10%62.14%64.50%60.34%78.12%
PRMath90.21%44.89%51.81%54.42%64.56%65.21%75.78%
PRLang89.12%58.54%65.32%69.54%74.56%75.32%83.24%
PRTime90.42%60.87%59.45%70.24%72.21%72.56%81.45%

发现 V:相对基于 LLM 的方法,CATGen 在开源基准上仍然最为有效。 如表 5 所示,在 Defects4J 上,现有方法在编译成功与结构覆盖率两方面已经取得较强结果,表明当前方法能够为环境相对稳定的开源项目生成可用的单元测试。在这一较强的基线性能之下,CATGen 在基于 LLM 的方法中仍取得最佳总体有效性。具体而言,CATGen 在所有基于 LLM 的技术中取得最高编译成功率(92.40%)与通过率(79.65%),并且在编译成功上仅略低于 EvoSuite(98.17%)。这与实践经验一致:Defects4J 风格的项目主要包含面向计算的逻辑、框架依赖有限,对 EvoSuite 等基于搜索的工具尤其有利。与此同时,CATGen 显著提高测试充分性:它在所有对比方法中取得最高行覆盖率(80.64%)与分支覆盖率(75.58%),超过传统基于搜索的生成(EvoSuite:62.44% / 53.08%)以及最强的基于 LLM 的基线(例如 RATester:72.85% / 66.32%)。这些结果表明,CATGen 在保持高水平可执行性的同时提高了覆盖率。

根据我们的经验,开源结果与我们在工业评估中的观察一致:稳定测试类骨架可以减少早期编译摩擦,轻量后处理有助于在不依赖迭代式 LLM 修复的情况下恢复常见问题。在环境通常更干净的开源项目中,这些机制表现为「可靠性放大器」——它们并不取代强大的基线能力,而是使生成的测试更一致地可执行,并在结构探索上更彻底。

表 6. Defects4J 上的变异分数(MS)。

项目EvoSuiteChatTesterChatUniTestHITSTELPARATesterCATGen
Chart58.2%50.1%48.6%53.4%57.8%60.2%66.9%
Math63.5%54.6%52.1%57.2%61.3%64.1%71.2%
Lang65.8%57.9%55.4%60.3%64.7%66.5%73.6%
Time57.6%48.8%47.2%52.1%55.9%58.7%67.4%
平均61.3%52.8%50.8%55.9%59.7%62.4%69.8%

发现 VI:以变异分数衡量,CATGen 提高了缺陷检测能力。 为进一步评估生成的测试在可执行性之外是否能有效检测缺陷,我们在 Defects4J 上评估变异分数(MS)。如表 6 所示,CATGen 在所有项目上持续取得最高变异分数,平均比最强基线(RATester)高出 7.4 个百分点。这表明编译成功与结构覆盖率的改进也转化为更强的缺陷检测能力。

有趣的是,尽管某些基线取得相对较高的行覆盖率或分支覆盖率,其变异分数仍然相对较低,说明高结构覆盖率并不必然意味着有效的缺陷检测。相比之下,CATGen 不仅生成可执行的测试,还产生更能杀死注入变异体的测试。这些结果突出了用基于变异的评估来补充 PR 与覆盖率等传统指标的重要性,并确认 CATGen 同时提高了可执行性与缺陷检测有效性。

6. 讨论

I. 案例研究与实践洞见。

图 4. 基线生成的单元测试

我们现在用图 3 中的案例(QC-32B)定性展示 CATGen 如何运作并优于基线。对应的被测方法见图 2(a)。基于结构化的测试类骨架,CATGen 在测试有效性上相对现有基线展现出明显优势。它生成的测试方法准确覆盖正常执行路径与异常执行路径。在成功情形中,CATGen 通过 when/thenReturn 配置 restTemplate.postForEntity(),使其返回包含期望数据、类型正确的 ResponseEntity(第 4 行),从而行使被测方法的主控制流。在异常情形中,它通过注入 when().thenThrow(new RestClientException("Error"))(第 11 行)模拟网络失败,确保被测方法正确处理该异常并将其重新抛出为 CommonException(第 13–14 行)。此外,CATGen 基于程序分析的增强组件识别出 LLM 经常忽略的未处理边界条件,例如空值,并生成专门的测试来显式覆盖这些情形。通过把这三种测试方法整合进一个连贯且结构良好的测试类,CATGen 实现对被测方法的全面功能覆盖。对同一被测方法,EvoSuite 在我们的设定中生成的测试未能编译,这反映了我们在工业仓库中反复遇到的挑战:框架装配、外部类型与所需初始化必须正确,任何测试逻辑才变得可执行。

转向图 4 中基于 LLM 的基线时,我们观察到不同的实践权衡。ChatTester 与 ChatUniTest 倾向于在真实或接近真实的运行时条件下行使系统,这使得在受控测试环境中复现网络失败等异常场景变得困难,除非诱发实际故障。HITS 确实纳入了 mock,但仍可能产生与预期服务行为不匹配的 mock,例如在需要 ResponseEntity 时返回原始 Map,从而削弱行为保真度。TELPA 由覆盖率反馈引导,往往试图快速到达未覆盖分支,但在我们的设定中它可能对测试装置的稳定性敏感,表现为直接用空依赖构造 RestTemplateService,并在没有通过 when 与 thenReturn 或 thenThrow 一致配置 postForEntity 的情况下调用 postForEntry。结果是,生成的测试可能因初始化不完整而过早失败。RATester 用仓库级符号与用法信息丰富生成,并且确实用 Mockito.mock 为 restTemplate.postForEntity 设置了 when 规则,但该测试仍然取决于脚手架与 mock 语义,例如对一个预期产生 ResponseEntity 的调用返回 null。这种失配可能把执行转移到另一条路径,并降低测试在工业项目约定下对目标服务行为的忠实程度。这些观察表明,对工业项目而言,纳入更广泛的上下文是有帮助的,而稳定测试类骨架与初始化仍然是把该上下文转化为可编译且行为有效的测试的前提。综合来看,定量评估与定性案例分析有力地加强了 CATGen 多阶段架构在应对基于 LLM 的单元测试生成挑战、尤其是工业场景中的挑战方面的有效性。

II. 用静态分析取代基于 LLM 的修复所得到的教训。 我们的结果表明,确定性程序分析比概率性的、基于 LLM 的修复产生更有效的后处理。为验证这一主张,我们进一步研究 CATGen 基于程序分析的后处理能够在多大程度上增强现有基线。具体而言,我们收集后处理之前的基线结果,然后用 CATGen 的后处理模块替换每个基线原有的后处理模块,并重新评估指标。我们用下标 w 表示修复前的结果,用 c 表示应用 CATGen 后处理之后的结果。与先前研究问题一样,我们使用 QC-32B 作为底层 LLM 以保持一致。

表 7. 不同后处理策略的有效性比较。

方法CovLCovBCSRPR
ChatTester48.20%49.60%73.03%51.57%
ChatTester_w43.93%43.57%63.36%44.32%
ChatTester_c49.95%50.17%83.49%52.82%
ChatUniTest45.92%46.78%71.06%45.96%
ChatUniTest_w38.53%40.05%59.05%38.33%
ChatUniTest_c50.81%56.20%80.04%48.51%
HITS54.47%56.45%67.68%46.55%
HITS_w48.18%50.19%65.30%41.75%
HITS_c59.01%63.70%85.28%53.35%

注:w = 无后处理;c = 使用 CATGen 的后处理组件。

表 7 所呈现的结果表明,把 CATGen 的后处理模块集成进基线,在所有评估指标上持续增强性能。对于 CovL,ChatTester 的性能从 48.20% 提高到 49.95%,ChatUniTest 从 45.92% 提高到 50.81%,HITS 从 54.47% 提高到 59.01%。在 CovB 上,ChatTester 从 49.60% 提高到 50.17%,ChatUniTest 从 46.78% 提高到 56.20%,HITS 从 56.45% 提高到 63.70%。CSR 显著上升:ChatTester 的 CSR 从 73.03% 提高到 83.49%,ChatUniTest 从 71.06% 提高到 80.04%,HITS 从 67.68% 提高到 85.28%。类似地,在 PR 上,ChatTester 从 51.57% 提高到 52.82%,ChatUniTest 从 45.96% 提高到 48.51%,HITS 从 46.55% 提高到 53.35%。值得注意的是,所有没有后处理的基线都表现更差,CSR 降到 66% 以下,PR 降到 46% 以下。这一鲜明对比突出了后处理在单元测试生成中的关键重要性。这些结果验证了:在后处理中,确定性程序分析优于启发式策略,尤其是对那些要求严格遵守代码正确性与执行稳定性的任务。这表明,使修复确定且以上下文为依据,是比增加更多 LLM 迭代更强的杠杆点,因为它在系统消除反复出现的编译器级失败模式的同时约束了成本。

III. 未来工作。 目前,CATGen 主要面向 Java 项目;未来工作将扩展其能力,以支持 Python、C++ 与 JavaScript 等主流编程语言,从而在多样的软件生态中实现更广泛的适用性。一个关键重点将是通过精炼推理工作流与后处理策略来优化模型推理效率,以增强在大规模工业项目中的可扩展性,同时降低生成时间与计算开销。为提高测试稳健性,我们将研究方法以生成更多样的测试用例,全面覆盖边界情形、边界条件与异常场景。这包括开发先进的条件分解算法与边界值分析技术,以系统应对测试不足的场景。

7. 效度威胁

外部效度。 对外部效度的一项潜在威胁来自模型选择与基线实现。为缓解这一点,我们在多种具有不同架构的先进 LLM 上评估 CATGen,包括通用模型与代码专用模型,以确保发现不绑定于单一模型。对基线,我们采用公开可得的实现,以保证公平且可复现的比较。我们的评估针对使用本地托管的开放权重模型、可复现的流水线级测试生成;我们不报告与交互式编码助手(例如 Claude Code 以及基于 Codex 的工具)的头对头实验,这些工具优化的是即兴的开发者交互,而不是在固定项目上下文下的批量生成,并且在保密协议(NDA)设定下对专有代码可能引发数据安全顾虑。

内部效度。 三个方面影响内部效度。第一,我们的覆盖率指标依赖 JaCoCo 进行运行时插桩,它可能遗漏某些执行路径,或在边界情形中误报覆盖率。尽管 JaCoCo 是 Java 测试中的标准工具,这一局限仍被承认。第二,LLM 的非确定性质可能给生成的测试引入变异。为应对这一点,我们对每种配置进行多次独立运行,并应用统计显著性检验,以确保所观察到的改进是一致的。第三,在第 4 节中把 CATGen 与基线对比时,我们在相同的被测方法上比较结果,使用成对的 Wilcoxon 符号秩检验(Woolson, 2007),报告 p 值以及效应量(r),并附带编译成功率、行覆盖率与分支覆盖率的相应变化。

构念效度。 我们把成功视为在项目约束下可编译、可执行的测试,而不仅仅是指标膨胀。工业基准强调部署失败模式,可能有利于以可编译性为中心的工作流;因此我们用 Defects4J 与变异分数分析加以补充。工业被测方法在 LLM 训练期间并非公开可得,通用修复模式也迁移到了 C 语言试点,但所有报告的实验都基于 Java。静态上下文抽取在我们的实现中使用 IntelliJ PSI,但只依赖 AST 级结构信号;任何提供等价事实的抽取器都可以替代 PSI。

8. 结论

LLM 近来在自动化单元测试生成上显示出前景,但我们的工业部署揭示出,令人鼓舞的研究结果与实际可用性之间仍存在持续差距。在真实项目中,生成的测试不仅必须达到覆盖率,还必须在复杂的项目级约束下编译并执行。根据我们的经验,我们观察到上下文不足、脚手架脆弱以及高成本的修复循环经常主导工作流,限制了现有提示驱动方法的收益。为应对这一点,我们引入一种经由反复工业失败而发展出来的上下文感知工作流。CATGen 并不依赖 LLM 去推断缺失的依赖,而是显式检索项目上下文、构造确定性的测试类骨架,并应用分析驱动的后处理以确保编译稳健性。在工业与开源两种设定中,相对现有基于 LLM 的方法,CATGen 都持续生成更可编译且更有效的测试,同时显著降低生成成本。我们的洞见鼓励未来工作把 LLM 视为工程化系统中的组件,而不是独立解决方案,并在把 AI 辅助测试技术带入真实开发环境时优先考虑稳健性与可部署性。

数据可用性

由于与工业伙伴的保密协议,本工作所使用的完整源代码与专有基准数据集不能公开发布。然而,为在这些约束下最大化可复现性与透明度,我们维护一个公开复现仓库,其中记录:所评估的 LLM 检查点与推理设置;静态上下文抽取的范围及其在有代表性的 IDE 解析器 API 之间的可移植性;确定性的、感知框架的测试骨架构造;第 3.4 节中的编译修复策略及其演算示例与排序依据;把 LLM 生成片段与分析驱动增强合并为一个测试类的归并规则;以及随该包发布的支持性 Java 解析工具,连同辅助的预处理与结果处理脚本。我们另外提供匿名化提示、有代表性的被测方法示例,以及与这些材料对齐的中间结果。复现仓库:https://github.com/CATGen-repository/CATGen

参考文献列表从略。

署名与许可

本文为 arXiv 论文 Context Matters: Improving the Practical Reliability of LLM-Based Unit Test Generation(arXiv:2607.19682)的中文全译。原文链接:https://arxiv.org/abs/2607.19682 。原文以 CC BY 4.0 许可发布。原作者:Junjie Chen、Ziqi Wang、Lin Yang、Chen Yang、Xiao Chu、Jianyi Zhou、Guangtai Liang、Qianxiang Wang、Dong Wang。译者:智测团队。

觉得有用,转给同事

微信扫码

用微信扫一扫,在手机上打开后即可转发。

用 RSS 订阅

提交勘误